1. 程式人生 > >Mysql覆蓋索引 covering index 或者 index coverage

Mysql覆蓋索引 covering index 或者 index coverage

查詢條件 auto pla 輔助 int mes sta png post

組合索引

提到組合索引,大家都知道“最左前綴”原則。例如,創建索引 idx_name_age (name,age) ,通常情況下,where age=50 或者 where age>50 之類的,是不會使用到idx_a_b的。那有沒有特殊情況呢?
假設表是:
CREATE TABLE users (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
email varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
password

varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
remember_token varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
created_at timestamp NULL DEFAULT NULL,
updated_at timestamp NULL DEFAULT NULL,
age int(11) DEFAULT NULL,
PRIMARY KEY (id),
UNIQUE KEY users_email_unique (email),
KEY idx_name_age (name
,age)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

覆蓋索引

innodb存儲引擎支持覆蓋索引(covering index),或稱索引覆蓋(index coverage),即從輔助索引中就能查到的記錄,而不需要查詢聚集索引中的記錄。
使用覆蓋索引的好處是輔助索引不包含整行記錄的所有信息,故其大小要遠小於聚集索引,因此可以減少大量的IO操作。

幾個sql語句的explain

  • explain SELECT name FROM test.users where age>50
    技術分享圖片

possible_keys是null,表示確實沒啥索引可用。
key卻是idx_name_age,表示優化器出動了,它選擇了idx_name_age這個二級索引。
註意select的字段是name,在idx_name_age這個二級索引中就能完成where的查找以及拿到select 的字段 name

  • explain SELECT name,age FROM test.users where age>50
    技術分享圖片

同上

  • explain SELECT name,age,id FROM test.users where age>50
    技術分享圖片

同上(註意二級索引都包含了主鍵[ 樣例表主鍵字段是id]以便通過主鍵去聚簇索引查找其他字段。但是顯然上述SQL語句並不需要,因為要select的字段在idx_name_age裏都有了。)

  • explain SELECT name,age,id,email FROM test.users where age>50
    技術分享圖片

這次沒有使用到idx_name_age,因為要select的字段包含了email,在idx_name_age裏面是沒有的

  • explain SELECT count(1) FROM test.users where age>50
    技術分享圖片

對於(a,b)這樣的聯合索引,對於b列的查詢條件進行統計,如果是覆蓋索引的,優化器也會選擇該聯合索引。

Mysql覆蓋索引 covering index 或者 index coverage