MySQL 可以建立複合索引(也就是說,多欄上的索引)。索引最多可以包含 16 欄。對於某些資料類型,您可以為欄建立前綴索引(請參閱第 10.3.5 節「欄索引」)。
MySQL 可以將多列索引用於測試索引中所有欄的查詢,或僅測試第一欄、前兩欄、前三欄等等的查詢。如果您在索引定義中以正確的順序指定欄,則單一複合索引可以加速同一資料表上的多種查詢。
多列索引可以視為排序的陣列,其中的列包含透過串連索引欄的值所建立的值。
作為複合索引的替代方案,您可以引入一個基於其他欄資訊的 「雜湊」 欄。如果此欄很短、具有合理的唯一性且已建立索引,則它可能比多欄的 「寬」索引更快。在 MySQL 中,使用這個額外欄非常容易
SELECT * FROM tbl_name
WHERE hash_col=MD5(CONCAT(val1,val2))
AND col1=val1 AND col2=val2;
假設一個資料表具有以下規格
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)
);
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';
但是,name
索引不會用於以下查詢中的查找
SELECT * FROM test WHERE first_name='John';
SELECT * FROM test
WHERE last_name='Jones' OR first_name='John';
假設您發出以下 SELECT
陳述式
SELECT * FROM tbl_name
WHERE col1=val1 AND col2=val2;
如果 col1
和 col2
上存在多列索引,則可以直接提取適當的列。如果 col1
和 col2
上存在個別的單列索引,則最佳化工具會嘗試使用索引合併最佳化(請參閱第 10.2.1.3 節「索引合併最佳化」),或嘗試找出限制性最強的索引,方法是決定哪個索引排除更多的列,並使用該索引來提取列。
如果表格有多個欄位的索引,最佳化工具可以使用索引的任何最左前綴來查找資料列。例如,如果您在 (col1, col2, col3)
上建立了一個三欄索引,您就可以使用 (col1)
、(col1, col2)
和 (col1, col2, col3)
進行索引搜尋。
如果查詢的欄位沒有形成索引的最左前綴,MySQL 無法使用索引來執行查找。假設您有以下顯示的 SELECT
語句。
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;
如果 (col1, col2, col3)
上存在索引,則只有前兩個查詢會使用索引。第三個和第四個查詢確實涉及索引的欄位,但由於 (col2)
和 (col2, col3)
不是 (col1, col2, col3)
的最左前綴,因此不會使用索引來執行查找。