MySQL SQL最佳化 - 覆蓋索引(covering index)
CREATE TABLE `user_group` (
`id` int(11) NOT NULL auto_increment,
`uid` int(11) NOT NULL,
`group_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `uid` (`uid`),
KEY `group_id` (`group_id`),
) ENGINE=InnoDB AUTO_INCREMENT=750366 DEFAULT CHARSET=utf8
看AUTO_INCREMENT就知道資料並不多,75萬條。簡單的查詢:
SELECT SQL_NO_CACHE uid FROM user_group WHERE group_id = 245;
-- SQL_NO_CACHE 不使用快取提示
Explain的結果是:
+----+-------------+------------+------+---------------+----------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+---------------+----------+---------+-------+------+-------+
| 1 | SIMPLE | user_group | ref | group_id | group_id | 4 | const | 5544 | |
+----+-------------+------------+------+---------------+----------+---------+-------+------+-------+
看起來已經用上索引了,資料分佈上,group_id相同的比較多,uid雜湊的比較均勻,加索引的效果一般,試著加了一個多列索引:
ALTER TABLE user_group ADD INDEX group_id_uid (group_id, uid);
這句SQL查詢的效能發生了巨大的提升,居然已經可以跑到0.00s左右了。經過最佳化的SQL再結合真實的業務需求,也從之前2.2s下降到0.05s。
再Explain一次
+----+-------------+------------+------+-----------------------+--------------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+-----------------------+--------------+---------+-------+------+-------------+
| 1 | SIMPLE | user_group | ref | group_id,group_id_uid | group_id_uid | 4 | const | 5378 | Using index |
+----+-------------+------------+------+-----------------------+--------------+---------+-------+------+-------------+
這種叫覆蓋索引(covering index),MySQL只需要透過索引就可以返回查詢所需要的資料,而不必在查到索引之後再去查詢資料,所以相當快!!但是同時也要求所查詢的欄位必須被索引所覆蓋到,在Explain的時候,輸出的Extra資訊中如果有“Using Index”,就表示這條查詢使用了覆蓋索引。
`id` int(11) NOT NULL auto_increment,
`uid` int(11) NOT NULL,
`group_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `uid` (`uid`),
KEY `group_id` (`group_id`),
) ENGINE=InnoDB AUTO_INCREMENT=750366 DEFAULT CHARSET=utf8
看AUTO_INCREMENT就知道資料並不多,75萬條。簡單的查詢:
SELECT SQL_NO_CACHE uid FROM user_group WHERE group_id = 245;
-- SQL_NO_CACHE 不使用快取提示
Explain的結果是:
+----+-------------+------------+------+---------------+----------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+---------------+----------+---------+-------+------+-------+
| 1 | SIMPLE | user_group | ref | group_id | group_id | 4 | const | 5544 | |
+----+-------------+------------+------+---------------+----------+---------+-------+------+-------+
看起來已經用上索引了,資料分佈上,group_id相同的比較多,uid雜湊的比較均勻,加索引的效果一般,試著加了一個多列索引:
ALTER TABLE user_group ADD INDEX group_id_uid (group_id, uid);
這句SQL查詢的效能發生了巨大的提升,居然已經可以跑到0.00s左右了。經過最佳化的SQL再結合真實的業務需求,也從之前2.2s下降到0.05s。
再Explain一次
+----+-------------+------------+------+-----------------------+--------------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+------------+------+-----------------------+--------------+---------+-------+------+-------------+
| 1 | SIMPLE | user_group | ref | group_id,group_id_uid | group_id_uid | 4 | const | 5378 | Using index |
+----+-------------+------------+------+-----------------------+--------------+---------+-------+------+-------------+
這種叫覆蓋索引(covering index),MySQL只需要透過索引就可以返回查詢所需要的資料,而不必在查到索引之後再去查詢資料,所以相當快!!但是同時也要求所查詢的欄位必須被索引所覆蓋到,在Explain的時候,輸出的Extra資訊中如果有“Using Index”,就表示這條查詢使用了覆蓋索引。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26870952/viewspace-2153164/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL 索引覆蓋(Covering Index)MySql索引Index
- Mysql索引覆蓋MySql索引
- MySQL 聚簇索引 和覆蓋索引MySql索引
- 技術分享 | MySQL 覆蓋索引最佳化案例一則MySql索引
- MySQL 覆蓋索引、回表查詢MySql索引
- MySQL 的覆蓋索引與回表MySql索引
- 【MySQL】三、效能優化之 覆蓋索引MySql優化索引
- MySQL優化之覆蓋索引的使用MySql優化索引
- mysql覆蓋索引高效能的探究MySql索引
- MySQL-覆蓋索引總結筆記MySql索引筆記
- mysql覆蓋索引之看山還是山MySql索引
- 什麼是覆蓋索引?索引
- 還傻傻分不清MySQL回表查詢與索引覆蓋?MySql索引
- 你的 SQL 還在回表查詢嗎?快給它安排覆蓋索引SQL索引
- 一篇文章講清楚MySQL的聚簇/聯合/覆蓋索引、回表、索引下推MySql索引
- 一文總結分析聚集索引、非聚集索引、覆蓋索引的工作原理!索引
- 從InnoDB 索引執行簡述 聚集索引和非聚集索引、覆蓋索引、回表、索引下推索引
- MySQL的索引最佳化MySql索引
- MySQL 8.0新特性-倒敘索引 desc indexMySql索引Index
- SQL效能最佳化之索引最佳化法SQL索引
- 最佳化SQL Server索引的技巧SQLServer索引
- 資料庫系列:覆蓋索引和規避回表資料庫索引
- MySQL 優化之 index_merge (索引合併)MySql優化Index索引
- SQL最佳化案例-分割槽索引之無字首索引(六)SQL索引
- 矩形覆蓋
- Elasticsearch之索引模板index template與索引別名index aliasElasticsearch索引Index
- 利用Lighthouse進行覆蓋率統計及其最佳化
- MySQL 索引使用策略及最佳化MySql索引
- MySQL中為什麼要使用索引合併(Index Merge)?MySql索引Index
- 最小圓覆蓋
- 棋盤覆蓋
- MySQL-10.索引最佳化與查詢最佳化MySql索引
- 程式碼覆蓋率與測試覆蓋率比較
- MySQL 索引和 SQL 調優總結MySql索引
- pandas(3):索引Index/MultiIndex索引Index
- 【INDEX】Postgresql索引介紹IndexSQL索引
- SQL最佳化案例-正確的使用索引(二)SQL索引
- SQL最佳化案例-自定義函式索引(五)SQL函式索引