无法使用索引的情况
- 索引的选择性太差的时候,不会用到索引,也就是重复的太多了,或者查询的范围太大了(个人经验结果大于总数的25%),导致mysql的查询优化器认为,直接对表进行全表扫描还更快,所以执行计划中干脆就不使用索引
- <>或者not in,无法使用索引
- is null会使用索引,is not null不会使用索引
- 联合索引要遵循左前缀原则
- 前缀索引要遵循左前缀原则
- 对索引列进行计算,或者使用函数进行加工
- 在WHERE子句中,如果在OR前的条件列是索引列,而在OR后的条件列不是索引列,那么索引会失效。
索引优化排序
单字段排序
假设idx_uid_sid(uid,source_id)复合索引
- 当排序出现了索引左侧列的时候,则可以使用索引进行排序
- 左侧字段单字段排序时候,索引可以升降序排序
explain select * from t_content where uid < 1000 order by uid desc;
当排序为索引右侧列的时候,就用到文件排序,using filesort,从排序的角度来看速度是比较慢的
explain select * from t_content where uid < 1000 order by source_id desc;
多字段排序
假设idx_uid_sid(uid,source_id)复合索引:
这个时候,左侧字段必须是升序,且字段的前后顺序不允许
-- 可以索引排序
explain select * from t_content where uid < 1000 order by uid,souce_id asc;
-- 左侧字段不是升序排序,无法利用索引进行排序
explain select * from t_content where uid < 1000 order by uid desc,souce_id asc;
-- 不可以索引排序,是file sort,因为uid顺序不是索引顺序
explain select * from t_content where uid < 1000 order by source_id,uid asc;
删除冗余索引
percona-toolkit工具
由于开发的时候,大家经常会各建个的索引,导致索引冗余,会占用磁盘空间,对表插入和更新操作的时候,会大量索引的重算,
- pt-duplicate-key-checker是percona-toolkit工具包中的实用组件,这个工具可以在语法层面上分析冗余索引
- 它可以帮助你检测表中重复的索引或者主键
首先下载:https://www.percona.com/downloads/percona-toolkit/LATEST/,然后选择对应的版本,直接解压到指定的目录即可
输入以下命令,就可以生成报表:
/usr/local/bin/pt-duplicate-key-checker --host=192.168.1.106 --user='mysql' --password='123456' --databases=test --tables=curs
sql查看索引运行情况
索引使用状况统计
SELECT
object_type,
-- 数据库名称
object_schema,
-- 表的名称
object_name,
-- 索引的名称,如果为null的话说明是进行全表扫描,要排查sql
index_name,
-- 索引在计算过程中读取了多少行
count_read,
-- 查询得到的结果是多少行
count_fetch,
-- 通过索引所操作的新增修改删除的数量
count_insert,
count_update,
count_delete
FROM
-- 从索引的角度,看下磁盘io的处理情况,相当于日志的统计表
performance_schema.table_io_waits_summary_by_index_usage
ORDER BY
-- 利用索引查询的总时间,可以看那个索引用的最多
sum_timer_wait DESC;
如果允许一段时间后,查询到的索引统计值都为0,说明索引没有被使用,可以删除
减少表和索引碎片
window系统中有一个碎片扫描和整理程序,它的作用是让我们的系统的文件更有效的组织在一起,让我们的io更加的流畅。在mysql中也存在这个问题,无论是表还是索引,在数据进行频繁的新增修改删除以后,往往都需要重新组织,但是在组织的过程中,必不可少的会有一些空间上的浪费,以及数据组织上的不合理的地方,如下两个命令就是用于解决这个问题的:
analyze table 表名
这个是索引重新统计。mysql底层对数据状况的重新统计,这个很重要,查询优化器优化sql是基于这个统计信息,对于innodb这种存储引擎,这种统计信息是一个估算值,频繁修改数据后,可能会导致统计信息不准确,隔一段时间有必要重新计算这些统计信息
optimize table 表名
这个是优化表空间,释放表空间。innodb的聚集索引,数据在磁盘中是顺序排列的,但是当数删除等操作的是,就会导致数据数据之间有间隙,并且无法被利用,这个命令就可以重新组织数据,重新利用这些间隙,查询效率就会提高。
执行这条命令会锁表,所以执行这条命令,要在维护期间执行,否则造成io阻塞。而且数据量很大的是,执行时间会很长。