關於最左匹配原則的解釋, 網上找了不少, 可是我感受都不是特別準確, 因而一怒之下 直接找了官網的文檔, 一會兒就清晰了. 下面貼下官網的解釋, 而後我本身翻譯了一下.html
原文連接mysql
MySQL can create composite indexes (that is, indexes on multiple columns). An index may consist of up to 16 columns. For certain data types, you can index a prefix of the column (see Section 8.3.5, 「Column Indexes」).sql
MySQL能夠建立聯合索引(即, 多列的索引). 一個索引能夠包含最多16列. 對於 某些數據類型, 你能夠索引列的前綴(這裏說的是對於Blob和Text類型, 索引列的前幾位就能夠, 如INDEX(blob_col(10)), 詳見索引文檔)app
MySQL can use multiple-column indexes for queries that test all the columns in the index, or queries that test just the first column, the first two columns, the first three columns, and so on. If you specify the columns in the right order in the index definition, a single composite index can speed up several kinds of queries on the same table.ide
MySQL的聯合索引能夠用於包含索引中全部列的查詢條件的語句, 或者包含索引中的第一列的查詢條件的語句, 以及索引中前兩列, 索引中的前三列, 以此類推. 若是你在索引定義中以正確的順序指定列, 那麼聯合索引就能夠加速同一張表中的多個不一樣類型的查詢.fetch
A multiple-column index can be considered a sorted array, the rows of which contain values that are created by concatenating the values of the indexed columns.優化
一個聯合索引能夠看做是一個有序隊列, 裏面有值的列是根據鏈接索引列的值建立的.(這句可能不許確)ui
Note
As an alternative to a composite index, you can introduce a column that is 「hashed」 based on information from other columns. If this column is short, reasonably unique, and indexed, it might be faster than a 「wide」 index on many columns. In MySQL, it is very easy to use this extra column:this
提示
做爲聯合索引的一個替代項, 你能夠採用一個Hash值列, 這個列的Hash值來自其餘的列. 若是該列簡短, 合理惟一, 且被索引, 那該列就可能比一個很"寬"的由多個列構成的索引 更快. MySQL裏能夠很容易的使用這種列:spa
SELECT * FROM tbl_name
WHERE hash_col=MD5(CONCAT(val1,val2))
AND col1=val1 AND col2=val2;
複製代碼
Suppose that a table has the following specification:
假設有以下表定義:
CREATE TABLE test (
id INT NOT NULL,
last_name CHAR(30) NOT NULL,
first_name CHAR(30) NOT NULL,
PRIMARY KEY (id),
INDEX name (last_name,first_name)
);
複製代碼
The name index is an index over the last_name and first_name columns. The index can be used for lookups in queries that specify values in a known range for combinations of last_name and first_name values. It can also be used for queries that specify just a last_name value because that column is a leftmost prefix of the index (as described later in this section). Therefore, the name index is used for lookups in the following queries:
索引name是一個包含了last_name和first_name列的索引. 該索引能夠用於爲last_name 和first_name值的組合指定一個已知範圍內的查詢. 一樣也能夠用於只指定了last_name列值的查詢, 由於這個列是索引的一個最左前綴(就以下一節所說). 所以, 索引name能夠用於下列的查詢語句:
SELECT * FROM test WHERE last_name='Jones';
SELECT * FROM test
WHERE last_name='Jones' AND first_name='John';
SELECT * FROM test
WHERE last_name='Jones'
AND (first_name='John' OR first_name='Jon');
SELECT * FROM test
WHERE last_name='Jones'
AND first_name >='M' AND first_name < 'N';
複製代碼
However, the name index is not used for lookups in the following queries:
然而, 索引name不能用於下列的查詢:
SELECT * FROM test WHERE first_name='John';
SELECT * FROM test
WHERE last_name='Jones' OR first_name='John';
複製代碼
Suppose that you issue the following SELECT statement:
假設存在如下select語句:
SELECT * FROM tbl_name
WHERE col1=val1 AND col2=val2;
複製代碼
If a multiple-column index exists on col1 and col2, the appropriate rows can be fetched directly. If separate single-column indexes exist on col1 and col2, the optimizer attempts to use the Index Merge optimization (see Section 8.2.1.3, 「Index Merge Optimization」), or attempts to find the most restrictive index by deciding which index excludes more rows and using that index to fetch the rows.
若是一個聯合索引存在於col1和col2, 相應的列會被直接抓取. 若是是分爲單獨的索引 分別存在於col1和col2, 優化器會嘗試利用索引聯合優化(詳見8.2.1.3, "索引聯合 優化"), 或者嘗試去尋找包含最多列, 最大限制的索引, 並利用該索引去抓取列.
If the table has a multiple-column index, any leftmost prefix of the index can be used by the optimizer to look up rows. For example, if you have a three-column index on (col1, col2, col3), you have indexed search capabilities on (col1), (col1, col2), and (col1, col2, col3).
若是表擁有一個聯合索引, 任何一個索引的最左前綴都會被優化器用於查找列. 好比, 若是你建立了一個三列的聯合索引包含(col1, col2, col3), 你的索引會生效於(col1), (col1, col2), 以及(col1, col2, col3)
MySQL cannot use the index to perform lookups if the columns do not form a leftmost prefix of the index. Suppose that you have the SELECT statements shown here:
若是查詢的列不是索引的最左前綴, 那MySQL不會將索引用於執行查詢. 假設你有 下列查詢語句:
SELECT * FROM tbl_name WHERE col1=val1;
SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;
SELECT * FROM tbl_name WHERE col2=val2;
SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;
複製代碼
If an index exists on (col1, col2, col3), only the first two queries use the index. The third and fourth queries do involve indexed columns, but do not use an index to perform lookups because (col2) and (col2, col3) are not leftmost prefixes of (col1, col2, col3).
若是索引存在於(col1, col2, col3), 那只有頭兩個查詢語句用到了索引. 第三個和 第四個查詢包含索引的列, 可是不會用索引去執行查詢. 由於(col2)和(col2, col3) 不是(col1, col2, col3)的最左前綴
其實官方文檔已經解釋的很是詳細了, 總結關於最左匹配的解釋, 那其實只有這麼 幾句話:
1.按照文檔, 更準確的說法應該是最左前綴原則, 即若是你建立一個聯合索引, 那 這個索引的任何前綴都會用於查詢, (col1, col2, col3)這個聯合索引的全部前綴 就是(col1), (col1, col2), (col1, col2, col3), 包含這些列的查詢都會啓用索 引查詢.
2.其餘全部不在最左前綴裏的列都不會啓用索引, 即便包含了聯合索引裏的部分列 也不行. 即上述中的(col2), (col3), (col2, col3) 都不會啓用索引去查詢.
注意, (col1, col3)會啓用(col1)的索引查詢
讀一下官方文檔, 還有不少別的發現, 跟最左前綴無關, 關於聯合索引的別的細節, 總結以下: