一、概述
合适的索引对良好的性能至关重要,不恰当的索引,反而可能影响性能;创建“最优”的索引,可能比好的索引性能高两个数量级,不过经常需要重写查询,所以索引优化和查询优化紧密相关。
索引对于小表并没有太大益处,对于中大型表则收益明显,对于特大型的表则无能为力,所以要避免特大表(如:超过1000w),如:进行分表。
索引是在存储引擎层实现的,而不是在服务层,不同存储引擎支持不同类型的索引,同一类型的索引在不同存储引擎的差异也可能很大。
索引优点
- 大量减少需要扫描的数据行数
- 避免使用临时表排序和分组
- 随机io转变为顺序io
MySQL支持的索引
- InnoDB:BTree
- MyISAM:BTree、RTree空间索引、全文索引
- Memory:hash索引
这里我们只讨论用到的最多的BTree索引,其他索引很多都有替代方案并不会使用MySQL实践
B-Tree索引
没有特别指明情况下指的都是B-Tree索引,InnoDB底层实际存储使用B+Tree,NDB使用T-Tree即使其名字是BTREE。(MyISAM和InnoDB底层实现略有不同,性能各有优略,此处不展开)
查找数据时,从索引根节点开始,逐渐向下层搜索,树的深度和表大小直接相关。
具体叶子页存储形式示例
B-Tree索引对下列查询有效
- 全值匹配:多列索引,匹配所有索引列
- 匹配最左前缀:多列索引,匹配索引的前几列
- 匹配列前缀:匹配某一列的前缀,如:匹配姓名的前4位,需要创建索引时创建为列前缀索引。
- 匹配范围值
- 精确匹配某一列并范围匹配另一列
- 只访问索引的查询:查询只访问索引,无需访问索引对应的数据行,称为索引覆盖。
索引是天然排序的,所以满足上述的查询的索引,同样可用于对应的order by、group by需求
B-Tree限制
- 必须按索引最左列开始查找,否则无法使用索引
- 不能跳过索引中的列
- 对某个索引列范围查询,则该列后边所有索引列无法使用索引
- 必须是独立的列,查询时不支持对索引列进行函数运算
二、高性能索引
sakila示例数据库
wget http://downloads.mysql.com/docs/sakila-db.tar.gz