MySql索引优化

81 阅读3分钟

索引下推

索引下推(index condition pushdown,ICP),如 like KK%

图片.png

图片.png

联合索引第一个字段用范围不会走索引,mysql内部可能觉得第一个字段就用范围,结果集应该很大,回表效率不高,还不如就全表扫描。若需要强制走索引 用force index

图片.png

order by与group by优化

1、MySQL支持两种方式的排序filesort和index,Using index是指MySQL扫描索引本身完成排序。index效率高,filesort效率低。 2、order by满足两种情况会使用Using index: 1)order by语句使用索引最左前列 2)使用where子句与order by子句条件列组合满足索引最左前列。 3,尽量在索引列上完成排序,遵循索引建立(索引创建的顺序)时的最左前缀法则。 4,如果order by 的条件不在索引列上,就会产生using filesort。 5,能用覆盖索引尽量使用覆盖索引。 6,group by与order by很类似,其实质是先排序后分组,遵照索引创建顺序的最左前缀法则。对于group by的优化如果不需要排序的可以加上order by null禁止排序。注意,where高于having,能写在where中的限定条件就不要去having限定了。

图片.png

图片.png

图片.png

索引中间字段不能断 所以第一个无using filesort(文件排序) 第二个using filesort 加上中间的字段后 第三条sql走了索引无using filesort 第四条sql 联合索引顺序打乱了 排序时age和position颠倒了 所以出现using filesort 图片.png

图片.png

图片.png

当age为常量 等于没有参与排序 在排序中被优化 所以联合索引未颠倒 没出现 using filesort 图片.png

排序升序降序方式不同 也会导致using filesort mysql8以上版本有降序索引可以支持该种查询方式 图片.png

多个条件也是范围查询 order by排序时 不走索引 图片.png

数据量太大 走了全表扫描 减少查询字段 用覆盖索引优化 图片.png

索引设计原则

图片.png

图片.png

图片.png

分页查询优化

1:根据自增且连续的主键排序的分页查询 图片.png

2:根据非主键字段排序的分页查询(让排序时返回的字段尽可能少,所以可以让排序和分页操作先查出主键,然后根据主键查到对应的记录) 图片.png

关联查询

1、嵌套循环连接 Nested-Loop Join(NLJ) 算法 一次一行循环地从第一张表(称为驱动表)中读取行,在这行数据中取到关联字段,根据关联字段在另一张表(被驱动表)里取出满足条件的行,然后取出两张表的结果合集。

图片.png

图片.png

2、基于块的嵌套循环连接 Block Nested-Loop Join(BNL)算法 把驱动表的数据读入到join buffer 中,然后扫描被驱动表,把被驱动表每一行取出来跟 join buffer 中的数据做对比。

图片.png

图片.png

图片.png 图片.png 图片.png

count(*)查询优化

图片.png 4种方式效率相同 图片.png

常见优化方法 1:查询mysql自己维护的总行数 对于myisam存储引擎的表做不带where条件的count查询性能是很高的,因为myuisam存储引擎的表的总行数会被musql存储在磁盘上,查询不需要计算 对于innodb存储引擎的表mysql不会存储表的总记录行数(因为有mvcc机制),查询count需要实时计算 图片.png

2 show table status 如果只需要知道表总行数的估计值可以用如下sql查询 图片.png

3 将总数威虎到redis里 插入或删除表数据行的时候同时维护redis里的表总行数kev的计数值(用incr或decr命令),但是这种方式可能不准,很难保证表操作和redis操作的事务一致性

4 增加数据库计数表 插入或删除表数据行的时候同时维护计数表,让他们在同一个事务里操作

阿里巴巴mysql规范

图片.png 图片.png 图片.png

图片.png

图片.png

图片.png

图片.png

图片.png

图片.png

图片.png

图片.png