在 MySQL 數(shù)據(jù)庫(kù)中,索引覆蓋是一種能夠提高查詢性能的優(yōu)化技術(shù)。它通過(guò)直接使用索引來(lái)返回查詢結(jié)果,在某些情況下可以避免查詢引擎對(duì)表進(jìn)行全表掃描而帶來(lái)的性能損耗。
索引覆蓋適用于以下場(chǎng)景:
1. 查詢的字段完全包含在某個(gè)索引中; 2. 查詢的是聚合函數(shù),如 SUM、AVERAGE 等; 3. 查詢語(yǔ)句使用 WHERE 子句的列都在同一個(gè)索引中,而且查詢條件是通過(guò) AND 連接的; 4. 查詢語(yǔ)句中只查詢索引列,而不需要查詢表中的非索引列;
當(dāng)滿足以上條件時(shí),MySQL 可以直接使用索引數(shù)據(jù)來(lái)返回結(jié)果,避免了讀取表數(shù)據(jù)的開銷,從而提升了查詢速度。
需要注意的是,在索引覆蓋場(chǎng)景下,MySQL 可能會(huì)選擇選擇多個(gè)索引進(jìn)行掃描,這種情況下需要權(quán)衡索引選擇的代價(jià)和掃描的效率,以達(dá)到最佳的查詢性能。
-- 索引覆蓋案例 CREATE TABLE `t_order` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '訂單ID', `user_id` int(11) NOT NULL COMMENT '用戶ID', `order_no` bigint(20) unsigned DEFAULT NULL COMMENT '訂單號(hào)', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時(shí)間', PRIMARY KEY (`id`), KEY `idx_user_id_order_no` (`user_id`,`order_no`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='訂單表'; -- 查詢用戶ID為10000,訂單號(hào)為123456的訂單數(shù)量 -- 該查詢符合索引覆蓋條件,使用索引可以直接返回結(jié)果,避免讀取表數(shù)據(jù)的開銷 EXPLAIN SELECT COUNT(*) FROM `t_order` WHERE user_id = 10000 AND order_no = 123456; +----+-------------+----------+------------+------+-----------------------+---------------+---------+-------+------+----------+------------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------+------------+------+-----------------------+---------------+---------+-------+------+----------+------------------------------------------------+ | 1 | SIMPLE | t_order | NULL | ref | idx_user_id_order_no | idx_user_id_order_no | 5 | const,const | 1 | 100.00 | Using index | +----+-------------+----------+------------+------+-----------------------+---------------+---------+-------+------+----------+------------------------------------------------+