mysql聯合索引的選擇性
聯合索引就是同時對錶中多個列進行索引,聯合索引會依次根據聯合索引中的列排序儲存。
下面透過下面的實驗來探討下聯合索引的使用選擇性:
版本:percona 5.6.27
create table test(
a int,
b int,
c int,
name varchar(32),
PRIMARY key(a),
key index_a_b_c(a,b,c)) ENGINE=INNODB
insert into test values(1,1,1,3,'leo');
insert into test values(2,1,2,1,'mike' );
insert into test values(3,1,3,1,'exo' );
insert into test values(4,1,2,3,'jhon' );
insert into test values(5,1,1,3,'lucy' );
insert into test values(6,2,2,3,'leo' );
insert into test values(7,3,1,2,'dv' );
insert into test values(8,2,1,3,'men' );
一:where條件對聯合索引的選擇性
mysql> explain select * from test where a=2;
+----+-------------+-------+------+---------------+-------------+---------+-------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+-------------+---------+-------+------+-------+
| 1 | SIMPLE | test | ref | index_a_b_c | index_a_b_c | 5 | const | 2 | NULL |
+----+-------------+-------+------+---------------+-------------+---------+-------+------+-------+
mysql> explain select * from test where a=2 and b=1;
+----+-------------+-------+------+---------------+-------------+---------+-------------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+-------------+---------+-------------+------+-------+
| 1 | SIMPLE | test | ref | index_a_b_c | index_a_b_c | 10 | const,const | 1 | NULL |
+----+-------------+-------+------+---------------+-------------+---------+-------------+------+-------+
mysql> explain select * from test where a=2 and b=2 and c=3;
+----+-------------+-------+------+---------------+-------------+---------+-------------------+------+-------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+-------------+---------+-------------------+------+-------+
| 1 | SIMPLE | test | ref | index_a_b_c | index_a_b_c | 15 | const,const,const | 1 | NULL |
+----+-------------+-------+------+---------------+-------------+---------+-------------------+------+-------+
這三個是正常的使用方法,都走了索引
mysql> explain select * from test where a=2 and c=3;
+----+-------------+-------+------+---------------+-------------+---------+-------+------+-----------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+-------------+---------+-------+------+-----------------------+
| 1 | SIMPLE | test | ref | index_a_b_c | index_a_b_c | 5 | const | 2 | Using index condition |
+----+-------------+-------+------+---------------+-------------+---------+-------+------+-----------------------+
1 row in set (0.00 sec)
如果把b漏掉,同樣走了索引
mysql> explain select * from test where b=2 and c=3;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | test | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)
mysql> explain select * from test where c=3;
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
| 1 | SIMPLE | test | ALL | NULL | NULL | NULL | NULL | 8 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+------+-------------+
如果把a漏掉,則不會走索引
結論:必須有聯合索引的第一個欄位作為wehre條件
二:聯合索引排序選擇性
聯合索引的排序會按照(a,b,c)的順序進行排序
測試資料在聯合索引的排序會是(1,1,3), (1,2,1), (1,2,3), (1,3,1), (2,1,3), (2,2,3), (3,1,2)順序儲存
mysql> explain select * from test where a=2 order by b;
+----+-------------+-------+------+---------------+-------------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+-------------+---------+-------+------+-------------+
| 1 | SIMPLE | test | ref | index_a_b_c | index_a_b_c | 5 | const | 2 | Using where |
+----+-------------+-------+------+---------------+-------------+---------+-------+------+-------------+
mysql> explain select * from test where a=2 order by c;
+----+-------------+-------+------+---------------+-------------+---------+-------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+-------------+---------+-------+------+-----------------------------+
| 1 | SIMPLE | test | ref | index_a_b_c | index_a_b_c | 5 | const | 2 | Using where; Using filesort |
+----+-------------+-------+------+---------------+-------------+---------+-------+------+-----------------------------+
可以看出第二個Using filesort使用了臨時表排序了,效率低。從聯合索引的排序就可以知道當指定a的值的時候,這些值會按b的值排序,不是按c的值排序,故order by b不用再filesort排序,反之order by b需要重新排序。
所以select * from test where a=2 and b=2 order by c;不會 filesort排序
mysql> explain select * from test where a=2 and b=2 order by c;
+----+-------------+-------+------+---------------+-------------+---------+-------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+------+---------------+-------------+---------+-------------+------+-------------+
| 1 | SIMPLE | test | ref | index_a_b_c | index_a_b_c | 10 | const,const | 1 | Using where |
+----+-------------+-------+------+---------------+-------------+---------+-------------+------+-------------+
結論:當針對聯合索引中的某個欄位進行排序的時候,最優的方法是有聯合索引排序欄位之前的欄位過濾條件
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29989552/viewspace-2132647/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MySQL字首索引和索引選擇性MySql索引
- MySQL的聯合索引MySql索引
- 組合索引的選擇原則索引
- MySQL查詢索引的選擇性、索引欄位、註釋等基本資訊的SQLMySql索引
- MySQL 查詢索引的選擇性、索引欄位、註釋等基本資訊的SQLMySql索引
- 【Mysql】InnoDB 中的聚簇索引、二級索引、聯合索引MySql索引
- 分割槽表全域性索引與本地索引的選擇索引
- MySQL 聯合索引測試3MySql索引
- MySQL索引選擇及規則整理MySql索引
- mysql 建立和刪除聯合索引MySql索引
- mysql 聯合索引的兩種特殊場景MySql索引
- 表資料量影響MySQL索引選擇MySql索引
- git合併分支,如果選擇性的合併檔案?Git
- Oracle建立索引選擇合適的可選項及效率問題Oracle索引
- MySQL建立表的時候建立聯合索引的方法MySql索引
- 為MySQL選擇合適的備份方式MySql
- 如何選擇合適的MySQL儲存引擎MySql儲存引擎
- MySQL innodb如何選擇一個聚簇索引MySql索引
- 索引的選擇原則索引
- mysql的組合索引MySql索引
- 如何選擇普通索引和唯一索引《死磕MySQL系列 五》索引MySql
- MySQL資料庫索引選擇使用B+樹MySql資料庫索引
- 面試 (MySQL 索引為啥要選擇 B+ 樹)面試MySql索引
- mysql索引為啥要選擇B+樹 (下)MySql索引
- mysql索引為啥要選擇B+樹 (上)MySql索引
- MySQL 調優之如何正確使用聯合索引MySql索引
- MySQL進階【五】—— MySQL查詢優化器是如何選擇索引的MySql優化索引
- mysql 索引合併MySql索引
- MySQL複合索引MySql索引
- MySQL學習之影響優化器選擇索引因素MySql優化索引
- Elasticsearch 中為什麼選擇倒排索引而不選擇 B 樹索引Elasticsearch索引
- mysql組合索引,abc索引命中MySql索引
- Oracle 計算欄位選擇性 判別列的索引潛力Oracle索引
- 【TUNE_ORACLE】列出走了低選擇性索引的SQL參考Oracle索引SQL
- JQuery選擇器——可見性篩選選擇器和屬性篩選選擇器jQuery
- MySQL 選錯索引的原因?MySql索引
- MySQL 選錯索引MySql索引
- [Mysql]索引選型MySql索引