B+树索引的使用
联合索引
联合索引是指对表上的多个列进行索引。
联合索引除了第一个列的键值有序外,其余列的键值也是有序的。
例如,在很多情况下应用程序都需要查询某个用户的购物情况,
并按照时间进行排序,最后取出最近三次的购买记录,
这时使用(userid, buy_date)联合索引将会避免一次排序的动作。
覆盖索引
InnoDB
存储引擎支持覆盖索引(covering index
,覆盖索引),即从辅助索引中
就可以得到查询的记录,而不需要查询聚集索引中的记录。
使用覆盖索引的一个好处是辅助索引不包含整行记录的所有信息,
故其大小要远小于聚集索引,一次IO可以读到更多的数据。
覆盖索引的另一个好处是对于某些统计问题而言。
如:SELECT COUNT(*) FROM t_table;
InnoDB
存储引擎并不会选择通过查询聚集索来进行统计。辅助索引远小于聚集索引,
选择辅助索引可以减少IO操作。
索引提示
MySQL
数据库支持索引提示(INDEX HINT
),显示告诉优化器使用哪个索引(但不是强制)。
使用索引提示的情况(仅做参考)
- 查询优化器使用了错误的索引。(很少)
- 可以选择的索引非常多,优化器选择执行计划的时间大于SQL本身的时间。
Multi-Range Read优化
MySQL 5.6
版本开始支持Multi-Range Read
(MRR
)优化,可对range
、ref
、eq_ref
类型的查询进行优化,使随机访问转化为顺序的数据访问。
MRR
优化有以下好处:
MRR
使数据访问变得较为顺序。在查询辅助索引时,首先根据得到的查询结果,按照主键进行排序,并按照主键顺序进行书签查找。
这里较为顺序的说法是对的,不一定查出来的主键就是连续的。
书签查找是啥意思?
减少缓冲池中页被替换的次数
没想明白
批量处理对键值的查询操作
对于InnoDB
和MyISAM
存储引擎的范围查询和JOIN
查询,MRR
的工作方式如下:
- 将查询得到的辅助索引值存放于一个缓存中,这时缓存中的数据是根据辅助索引键值排序的
- 将缓存中的键值根据
RowID
进行排序。 - 根据
RowID
的排序顺序来访问实际的数据文件。
Index Condition Pushdown (ICP) 优化
索引下推, MySQL 5.6
开始支持的一种根据索引进行查询的优化方式。
不支持ICP
之前,当进行索引查询时,首先根据索引来查找记录,然后根据WHERE
条件过滤记录。
支持ICP
之后,MySQL
在取出索引的同时,判断是否可以进行WHERE
条件过滤,也就是将部分过滤
操作放在了存储引擎层。
WHERE
可以过滤的条件是要该索引可以覆盖到的范围。