Mysql覆蓋索引 covering index 或者 index coverage


組合索引

提到組合索引,大家都知道“最左前綴”原則。例如,創建索引 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列的查詢條件進行統計,如果是覆蓋索引的,優化器也會選擇該聯合索引。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM