关于最左匹配原则的解释, 网上找了不少, 可是我感受都不是特别准确, 因而一怒之下 直接找了官网的文档, 一会儿就清晰了. 下面贴下官网的解释, 而后我本身翻译了一下.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)的索引查询
读一下官方文档, 还有不少别的发现, 跟最左前缀无关, 关于联合索引的别的细节, 总结以下: