MySQL高性能的索引策略(三)

MySQL高性能的索引策略(三)mysql

使用覆蓋索引sql

若是索引包含知足查詢的全部數據,就稱爲覆蓋索引。覆蓋索引是一種很是強大的工具,能大大提升查詢性能。只須要讀取索引而不用讀取數據有如下一些優勢:緩存

(1)索引項一般比記錄要小,因此MySQL訪問更少的數據;服務器

(2)索引都按值的大小順序存儲,相對於隨機訪問記錄,須要更少的I/O;工具

(3)大多數據引擎能更好的緩存索引。好比MyISAM只緩存索引。性能

(4)覆蓋索引對於InnoDB表尤爲有用,由於InnoDB使用匯集索引組織數據,若是二級索引中包含查詢所需的數據,就再也不須要在彙集索引中查找了。優化

覆蓋索引不能是任何索引,只有B-TREE索引存儲相應的值。並且不一樣的存儲引擎實現覆蓋索引的方式都不一樣,並非全部存儲引擎都支持覆蓋索引(Memory和Falcon就不支持)。spa

覆蓋索引的實際應用,以下表結構,code

CREATE TABLE people (
   id int not null AUTO_INCREMENT,
   last_name varchar(50)    not null,
   first_name varchar(50)    not null,
   dob        date           not null,
   gender     enum('m', 'f') not null,
   primary key (id),
   key(last_name, first_name, dob)
);

以下查詢,explain,索引

> explain select id , last_name , first_name from people

******************** 1. row *********************
           id: 1
  select_type: SIMPLE
        table: people
         type: index
possible_keys: 
          key: last_name
      key_len: 107
          ref: 
         rows: 1
        Extra: Using index
1 rows in set

能夠看到Extra列是 Using index,因此只在二級索引中就找到了須要的數據,不要再去聚簇索引中根據主鍵查找須要的數據行。

可是要注意的是否是全部的類型的索引均可以成爲覆蓋索引。覆蓋索引必需要存儲索引列的值,而哈希索引,空間索引和全文索引等都不存儲索引列的值,索引mysql只能使用

B-Tree索引作覆蓋索引。另外,不一樣的存儲引擎實現覆蓋索引的方式也不一樣,並且不是全部的引擎都支持覆蓋索引。

咱們再來看下面這種狀況。假設索引覆蓋了WHERE條件中的字段,但不是整個查詢涉及的字段。

> explain
select * from people where last_name = 'hello' and first_name like '&hello&'

******************** 1. row *********************
           id: 1
  select_type: SIMPLE
        table: people
         type: range
possible_keys: last_name
          key: last_name
      key_len: 104
          ref: 
         rows: 1
        Extra: Using index condition
1 rows in set

好,看到了吧,出現了using index condition,先把mysql的ICP(索引條件推送)優化關掉,

set optimizer_switch = 'index_condition_pushdown=off';

> explain
select * from people where last_name = 'hello' and first_name like '&hello&'

******************** 1. row *********************
           id: 1
  select_type: SIMPLE
        table: people
         type: range
possible_keys: last_name
          key: last_name
      key_len: 104
          ref: 
         rows: 1
        Extra: Using where
1 rows in set

這裏的索引沒法覆蓋該查詢,有兩個緣由:

  1. 沒有任何索引覆蓋這個查詢。由於查詢從表中選擇了全部的列,而沒有任何索引覆蓋了全部的列。

  2. mysql不能在索引中執行like操做。這是底層存儲引擎API的限制。由於若是是通配符開頭的like查詢,存儲引擎就沒法比較匹配。這種狀況下,mysql服務器只能提取數據行的值而不是索引的值來作比較。

=============END=============

相關文章
相關標籤/搜索