2014/01/23

Mysql索引覆盖covered index

什么是索引覆盖

就是select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖。
那么显然select * from ...是一种拙劣的查询,除非你建立了包含所有列的索引(这样建索引脑子进水)。

对 于索引覆盖查询(index-covered query),使用EXPLAIN时,可以在Extra一列中看到“Using index”。

使用索引覆盖

如果你想要通过索引覆盖select多列,那么需要给需要的列建立一个多列索引,当然如果带查询条件,where条件要求满足最左前缀原则。
Innodb的辅助索引叶子节点包含的是主键列,所以主键一定是被索引覆盖的。

(1)例如,在sakila的inventory表中,有一个组合索引(store_id,film_id),对于只需要访问这两列的查 询,MySQL就可以使用索引,如下:
mysql> EXPLAIN SELECT store_id, film_id FROM sakila.inventory\G
*************************** 1. row ***************************
        id: 1
select_type: SIMPLE
        table: inventory
        type: index
possible_keys: NULL
        key: idx_store_id_film_id
        key_len: 3
        ref: NULL
      rows: 5007
      Extra: Using index
1 row in set (0.17 sec)

(2)再比如说在文章系统里分页显示的时候,一般的查询是这样的(转):
SELECT id, title, content FROM article ORDER BY created DESC LIMIT 10000, 10;
通常这样的查询会把索引建在created字段(其中id是主键),不过当LIMIT偏移很大时,查询效率仍然很低,改变一下查询:
SELECT id, title, content FROM article
INNER JOIN (
    SELECT id FROM article ORDER BY created DESC LIMIT 10000, 10
) AS page USING(id)
此时,建立复合索引"created, id"【只要建立created索引就可以吧,Innodb是会在辅助索引里面存储主键值的】,就可以在子查询里利用上Covering Index,快速定位id,查询效率嗷嗷的