mySQL索引优化几大原则

mySQL索引优化几大原则

1、mysql索引尽量减少回表操作;

比如一张表有 id,name,sex 这几个字段,只是对name做了索引(没做覆盖索引),select*from table where name=“a” ,这句sql查询的时候会涉及回表,它会优先找到name=“a”那个叶子节点(其中包含了该条数据的id),然后在根据id从新回去找该id的所有数据,相当于再次走索引,才能找到sex这个字段的值。如果要解决这个回表就建覆盖索引(联合索引)就是建索引的时候name与sex组合成一个索引,这样一次就能找到name和sex 聚集索引(默认是主键,如果没有是设置了not null或者unique的字段):它包含了该条数据的所有字段。

2、关联表查询的时候大小表如何放?(使用短索引, 提高索引访问时的I/O效率)

小表驱动大表,为什么小表驱动大表速度快?

2.1、多表join,类似于循坏嵌套,外面的循环5次,里面循环1000次,如果小的循环结果在外面,对于数据库连接只连接5次,进行5000次操作,如果大的循环结果在外面,需要数据库连接1000次,从而浪费资源,增加消耗;

比如部门表dept(id),(数据大的表)员工表emp(id,dept_id)select*from emp,dept where emp.dept_id=dept.id 数据库查询的时候是优先得到dept.id然后再去和emp.dept_id去匹配相等,这样缩小了匹配范围,搜索效率也会提升。

3、like查询遵循最左匹配原则;

尽量不要在被查询的字段计算等未能确定数值的操做,like模糊搜索不一定,会导致索引失效,我们可以从索引的底层数据结构分析,它是一个B+树结构,B+树有个特点,左子树的值比右子树的值小,它是一个把你存进来的数据按照某个区域顺序排好在树上,当我们查询某个值的时候优先计算这个值得hash,计算完就从树上匹配。如果like 的%在前面比如(%es),就会不知道该数据如何从树上去查找,所以导致找不到,要走索引一定要遵循最左匹配,另外同理,一些需要计算的值有不确定性,因此也会找不到它会落到树的哪片区域,就走不了索引。

4、分页查询的时候limit到后面会越来越慢;

越来越慢的原因是比如limit 10,10 它要扫描前10条后丢弃再找10条出来,然后limit 100,10,它要扫描100条,扫描越多io就会越多,因此要想方法让它走索引,比如表是自增的,我们查询limit100000,10的时候,我们可以select name from emp where id>(上次的大小,比如这里是10000) limit 10,这样的话效率就会高了很多

5、尽可能的使用 varchar 代替 char ;

char是一种固定长度的类型,varchar则是一种可变长度的类型 
尽可能的使用 varchar 代替 char ,因为首先变长字段存储空间小,可以节省存储空间, 
其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。

6、应尽量避免在 where 子句中使用 or 来连接条件;

如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描;

7、应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。

8、不做列运算:where age + 1 = 10;

任何对列的操作都将导致表扫描,它包括数据库教程函数.计算表达式等, 都会是索引失效.

9、解决联表查询时关联字段字符集不一样问题(会报错)

10、尽量避免子查询,将子查询优化多表查询;

一般来讲连接查询效率更高,因为子查询会多次遍历数据,而连接查询只遍历一次,但是如果数据量较少的话子查询更加容易控制。但如果数据量大的话两者的区别就会很明显,对于数据量多的肯定是用连接查询快;

11、 为什么区分不高的字段不合适加索引?索引怎么存储B+?

MySQL是B+存储的,索引是为了提高数据检索效率,降低磁盘io速度,因为我们数据存在磁盘上,我们要去磁盘加载数据的时候,就会涉及磁盘的io,所以要去减少磁盘io的一个次数,去提高性能。那为什么不用b树而是用B+,他就要考虑到我们MySQL关系型数据库本身的一个特性,不是说B树不行,不如MangoDB就是使用B树,技术没有好坏,所以在这里面他B+的好处就是:1、我们可以进行范围查找的时候,会更方便,因为B+树只需要去遍历叶子节点就可以实现整棵树的遍历,而B树则需要通过从根节点从上往下的遍历 2、降低磁盘io次数,因为B+非叶子节点存储数据是索引结构,叶子节点存储是实际数据,而B树非叶子节点和叶子节点存储是实际数据,MySQL每页大小是16K,B+树非叶子节点的数据量更小了,高度就会变矮 ,尽可能的降低磁盘io访问次数;

当使用 区分度不高的字段做索引的时候,就会可能造成遍历整个B+树的每个分支,比如说用使用性别男女这个字段加索引,意味着男女这个数据会存在相同,那么它会存在B+树上,就会造成很多分支都会进行一个存储,所以就会导致性能下降。

猜你喜欢

转载自blog.csdn.net/weixin_56602545/article/details/130380175