文件首頁
MySQL 8.4 參考手冊
相關文件 下載本手冊
PDF (美式信紙) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 參考手冊  /  ...  /  多欄索引

10.3.6 多欄索引

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_namefirst_name 欄位的索引。該索引可用於在查詢中尋找指定 last_namefirst_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;

如果 col1col2 上存在多欄索引,則可以直接擷取適當的列。如果 col1col2 上存在單獨的單欄索引,則最佳化工具會嘗試使用索引合併最佳化 (請參閱第 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) 的最左前綴,因此不會使用索引來執行查找。