在 MySQL 數據庫中,索引覆蓋是一種能夠提高查詢性能的優化技術。它通過直接使用索引來返回查詢結果,在某些情況下可以避免查詢引擎對表進行全表掃描而帶來的性能損耗。
索引覆蓋適用于以下場景:
1. 查詢的字段完全包含在某個索引中; 2. 查詢的是聚合函數,如 SUM、AVERAGE 等; 3. 查詢語句使用 WHERE 子句的列都在同一個索引中,而且查詢條件是通過 AND 連接的; 4. 查詢語句中只查詢索引列,而不需要查詢表中的非索引列;
當滿足以上條件時,MySQL 可以直接使用索引數據來返回結果,避免了讀取表數據的開銷,從而提升了查詢速度。
需要注意的是,在索引覆蓋場景下,MySQL 可能會選擇選擇多個索引進行掃描,這種情況下需要權衡索引選擇的代價和掃描的效率,以達到最佳的查詢性能。
-- 索引覆蓋案例 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 '訂單號', `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創建時間', PRIMARY KEY (`id`), KEY `idx_user_id_order_no` (`user_id`,`order_no`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='訂單表'; -- 查詢用戶ID為10000,訂單號為123456的訂單數量 -- 該查詢符合索引覆蓋條件,使用索引可以直接返回結果,避免讀取表數據的開銷 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 | +----+-------------+----------+------------+------+-----------------------+---------------+---------+-------+------+----------+------------------------------------------------+