5.4.1 支持多种过滤条件
and sex in ('m','w')
? 来让mysql选择该索引(注意:只有很少的列才可以这么使用)
- 尽可能将需要做范围查询的列放到索引的后面,以便优化器能使用尽可能多的索引列
5.4.2 避免多个范围条件
对于范围条件查询,mysql无法再使用范围列后面的其它索引列了。
5.4.3 优化排序
对于limit而言,随着偏移量的增加,mysql需要花费 大量的时间来扫描需要丢弃的数据。
优化这类索引一个比较好的策略是使用延迟关联。通过使用覆盖索引查询需要返回的主键,再根据这些主键关联原来的表获取需要的行。
EXPLAIN SELECT id from account
# 解释
type index
key primary
using index
没有where 条件,select 只有主键。使用的是主键索引查询的。
5.5 维护索引和表
找到并修复损坏的表,维护准确的索引统计信息,减少碎片
5.5.1 找到并修复损坏的表
一些不应该发生的错误,可以尝试check table 来检查表是否有损坏。可以使用 repair table 命令来修复损坏的表
5.5.2 更新索引统计信息
mysql 的查询优化器通过两个api来了解存储引擎的索引的分布信息,以决定如何使用索引
- records_in_range(),通过向存储引擎传入两个边界值获取这个范围内大概多少条记录,对于myisam 是精确值,innodb是估算值
- info(),该接口返回各种类型的数据,包括索引的基数(每个键值有多少条数据)
如果存储引擎向优化器提供的扫描行数信息是不准确的数据,或者执行计划本身太复杂以致无法准确地获取各个阶段匹配的行数,那么优化器会使用索引统计信息来估算扫描行数。
5.5.3 减少索引和数据的碎片
B-Tree 索引可能会碎片化,这会降低查询的效率。碎片化的索引可能会很差或者无序的方式存储在磁盘上。
行碎片:
? 是数据行被存储为多个地方的多个字段中。即使从索引中访问一条记录,行碎片也会导致性能下降
行间碎片:
? 行间碎片是指逻辑上顺序的页,或者行在磁盘上不是顺序存储的。对全表扫描和聚簇索引扫描之类影响很大
剩余空间碎片:
? 指页中有大量空余空间,会导致服务器读取大量不需要的数据,从而造成浪费
对于MyISAM ,这三种情况都会出现,InnoDB不会出现短小的行碎片,InnoDB会移动短小的行并重写到一个片段中。
可以通过optimize table或者导出再导入的方式来重新整理数据。
5.6 总结
在选择索引和编写利用这些索引查询时,如下三个原则:
- 选择合适的索引以避免单行查找
- 尽可能使用 数据原生顺序避免额外的排序
- 尽可能使用覆盖索引
|