有很多面试官喜欢问:“什么是数据库优化”,“怎么去优化数据库”,可是一般问这个问题的面试官自己都可能不知道答案,而我们则喜欢回答:“少取字段,建立合理的索引”,可是就这么模糊其词的答案往往不是面试官想要的答案。
回答這个问题,最主要的就是具体,把优化的方法具体分层次的答出来,这才是面试官想要的回答,为此我总结了一下几点(工作中以下几点也是有点用处的)
一、表的优化和列类型选择
表的优化:
1:定长与变长分离
如 ID int,占4个字节,char(4)占四个字符长度,也是定长
time即每一单元值占的字节是固定的
核心且常用的字段,宜建成定长,放在一张表
而varchar,text,blob这种变长字段,适合单放在一张表里,用主建与核心表关联
2、常用字段和不常用字段要分离
需要结合项目的具体业务来分析,分析字段的查询场景,查询频度低的字段单拆出来
3、在1对多需要关联统计的字段上添加冗余字段
列选择原则:
1:字段类型的优先级 整型>date,time>char>varchar>blob,text
2: 够用就行,不要康概 (enum('男','女'))
3:尽量避免使用NULL()
原因:null不利于索引,要用特殊的字节来表示
二、索引优化策略
1:索引类型(高效查询的数据结构,提高排序速度,提高分组统计的速度)
1.1 B-tree 索引
注:名叫btree索引,大的方面来看,都用的平衡树,但具体的实现上,各引擎稍有
不同,比如严格的说NDB引擎,使用的是T-tree
MYISAM.INNODB中默认用B-tree
抽象细想 B-tree系统可理解为“排好序的快速查找结构”
1.2 hash索引
在memory表里默认是使用hash索引,hash的理论查询时间复杂度为0(1)
注memory表示内存引擎表
2:btree索引的常见误区
2.1 在where条件常用的列上都加上索引
列:where car_id=3 and price>100:
误:cat_id 和price上都建立索引
错:只能用上car_id或price索引,因为是独立的索引,同时只能用一个
2.2 在多列上建立索引后,查询那个列,索引都将发生作用(左前缀原则,过桥原理)
注:explain sql语句:解释语句
三、聚簇索引和非聚簇索引
innodb的主索引上,直接存放该行数据,成为聚簇索引,次索引指向主键的应用
myisan中,主键索引和次索引,都指向物理行(磁盘的位置)
注意:innodb来说:
1:主键索引, 既存储索引值,又在叶子中存储行的数据
2:如果没有主键(primary key),则会Unique key做主键
3:如果没有unique,则系统会生成一个内部的rowid做主键
4,:像innodb中,主键的索引结构中,既存储了主键值,又存储了行数据
这种结构称为“聚簇索引”
聚簇索引
优势:根据主键查询条目比较少时,不用回行
劣势:如果碰到不规则数据插入时,造成频繁的叶分裂
四、索引覆盖
索引覆盖是指,如果查询的列恰好是索引的一部分,那么查询只需要在索引文件上进行
不需要回行到磁盘再找数据
这种查询速度非常快,称为“索引覆盖”
五、理想索引
1、查询频繁 2、区分度高 3、长度小 4、尽量能覆盖常用查询字段
select((select count(distinct left(字段,1)) from 表名) / (select count(*) from 表名))
5.2:如果左前缀很难区分的字段怎么建索引
倒序建立
伪哈希技巧
crc32是一种哈希算法,能把字符串算成32位整数
echo crc32('http://www.baidu.com')
5.3 多列索引要考虑的因素
5.3.1 多列索引的考虑因素 列查询的频率、列的区分度、注意一定要结合实际的业务场景
六、索引碎片与为维护
6.1 碎片是在数据不断变化中产生的(铺地板例子)
修复碎片 nop操作(不产生对数据实质影响的操作)
optimize table 表名
七、sql语句优化
7.1 sql语句的时间花在哪儿?
答:等待时间、执行时间
7.2 sql语句的执行时间,又花在哪儿?
答:查找--》顺着索引查找,慢着可能全表扫描
取出--》查到行后,把数据取出来(sending date)
7.3 如何查询快?
答:查询的快 -- 联合索引的顺序,区分度,长度
取得快,索引覆盖
传输的少,更少的行和列
7.4 切分查询:按数据折成多次
列:插入10000行数据,每1000为单位插入
分解查询:按逻辑把多表的连接查询分成多个简单的sql
7.5 sql语句的优化思路
答:不查-》少查-》高效的查
不查:通过业务逻辑来计算
少查:劲量精准数据少取行
必须要查:尽量走在索引上查询行