索引提示為最佳化器提供關於在查詢處理期間如何選擇索引的資訊。此處描述的索引提示,與 第 10.9.3 節「最佳化器提示」中描述的最佳化器提示不同。索引提示和最佳化器提示可以單獨使用或一起使用。
索引提示適用於 SELECT
和 UPDATE
語句。它們也適用於多資料表 DELETE
語句,但不適用於單一資料表 DELETE
,如本節稍後所示。
索引提示指定在資料表名稱之後。(關於在 SELECT
語句中指定資料表的一般語法,請參閱 第 15.2.13.2 節「JOIN 子句」。)引用個別資料表(包括索引提示)的語法如下:
tbl_name [[AS] alias] [index_hint_list]
index_hint_list:
index_hint [index_hint] ...
index_hint:
USE {INDEX|KEY}
[FOR {JOIN|ORDER BY|GROUP BY}] ([index_list])
| {IGNORE|FORCE} {INDEX|KEY}
[FOR {JOIN|ORDER BY|GROUP BY}] (index_list)
index_list:
index_name [, index_name] ...
USE INDEX (
提示告訴 MySQL 只使用其中一個命名的索引來尋找資料表中的列。替代語法 index_list
)IGNORE INDEX (
告訴 MySQL 不要使用某些特定索引。如果 index_list
)EXPLAIN
顯示 MySQL 使用了錯誤的索引,這些提示很有用。
FORCE INDEX
提示的作用類似於 USE INDEX (
,但附加了假設資料表掃描 非常 昂貴。換句話說,只有在沒有辦法使用其中一個命名的索引來尋找資料表中的列時,才會使用資料表掃描。index_list
)
MySQL 9.0 支援索引層級最佳化器提示 JOIN_INDEX
、GROUP_INDEX
、ORDER_INDEX
和 INDEX
,這些提示等同於且旨在取代 FORCE INDEX
索引提示,以及 NO_JOIN_INDEX
、NO_GROUP_INDEX
、NO_ORDER_INDEX
和 NO_INDEX
最佳化器提示,這些提示等同於且旨在取代 IGNORE INDEX
索引提示。因此,您應該預期 USE INDEX
、FORCE INDEX
和 IGNORE INDEX
將在 MySQL 的未來版本中被棄用,並在一段時間後完全移除。
這些索引層級最佳化器提示支援單表和多表 DELETE
陳述式。
如需更多資訊,請參閱 索引層級最佳化器提示。
每個提示都需要索引名稱,而不是欄名稱。若要參照主索引鍵,請使用名稱 PRIMARY
。若要查看表格的索引名稱,請使用 SHOW INDEX
陳述式或資訊綱要 STATISTICS
表格。
index_name
值不需要是完整的索引名稱。它可以是索引名稱的明確前綴。如果前綴不明確,則會發生錯誤。
範例
SELECT * FROM table1 USE INDEX (col1_index,col2_index)
WHERE col1=1 AND col2=2 AND col3=3;
SELECT * FROM table1 IGNORE INDEX (col3_index)
WHERE col1=1 AND col2=2 AND col3=3;
索引提示的語法具有以下特點
在語法上,省略
USE INDEX
的index_list
是有效的,這表示「「不使用任何索引。」」。省略FORCE INDEX
或IGNORE INDEX
的index_list
則為語法錯誤。您可以透過在提示中新增
FOR
子句來指定索引提示的範圍。這可以更精細地控制最佳化器對於查詢處理各個階段的執行計畫選擇。若要僅影響 MySQL 在決定如何尋找表格中的資料列以及如何處理聯結時使用的索引,請使用FOR JOIN
。若要影響用於排序或分組資料列的索引使用,請使用FOR ORDER BY
或FOR GROUP BY
。您可以指定多個索引提示
SELECT * FROM t1 USE INDEX (i1) IGNORE INDEX FOR ORDER BY (i2) ORDER BY a;
在多個提示中(即使在同一個提示中)命名相同的索引並不是錯誤
SELECT * FROM t1 USE INDEX (i1) USE INDEX (i1,i1);
但是,對同一個表格混合使用
USE INDEX
和FORCE INDEX
則為錯誤SELECT * FROM t1 USE INDEX FOR JOIN (i1) FORCE INDEX FOR JOIN (i2);
如果索引提示不包含 FOR
子句,則提示的範圍會套用至陳述式的所有部分。例如,此提示
IGNORE INDEX (i1)
等同於此提示組合
IGNORE INDEX FOR JOIN (i1)
IGNORE INDEX FOR ORDER BY (i1)
IGNORE INDEX FOR GROUP BY (i1)
當處理索引提示時,會依類型(USE
、FORCE
、IGNORE
)和範圍(FOR JOIN
、FOR ORDER BY
、FOR GROUP BY
)將其收集到單一清單中。例如
SELECT * FROM t1
USE INDEX () IGNORE INDEX (i2) USE INDEX (i1) USE INDEX (i2);
等同於
SELECT * FROM t1
USE INDEX (i1,i2) IGNORE INDEX (i2);
然後,索引提示會依下列順序套用至每個範圍
如果存在,則會套用
{USE|FORCE} INDEX
。(如果不存在,則會使用最佳化器決定的索引集。)IGNORE INDEX
會套用至上一步的結果。例如,以下兩個查詢是等效的SELECT * FROM t1 USE INDEX (i1) IGNORE INDEX (i2) USE INDEX (i2); SELECT * FROM t1 USE INDEX (i1);
對於 FULLTEXT
搜尋,索引提示的運作方式如下
對於自然語言模式搜尋,索引提示會被靜默忽略。例如,
IGNORE INDEX(i1)
會被忽略且不會有警告,索引仍會使用。對於布林模式搜尋,具有
FOR ORDER BY
或FOR GROUP BY
的索引提示會被靜默忽略。具有FOR JOIN
或沒有FOR
修飾符的索引提示則會被採用。與提示如何套用於非FULLTEXT
搜尋的情況相反,此提示會用於查詢執行的所有階段(尋找資料列和檢索、分組和排序)。即使提示是針對非FULLTEXT
索引給定的,也是如此。例如,以下兩個查詢是等效的
SELECT * FROM t USE INDEX (index1) IGNORE INDEX FOR ORDER BY (index1) IGNORE INDEX FOR GROUP BY (index1) WHERE ... IN BOOLEAN MODE ... ; SELECT * FROM t USE INDEX (index1) WHERE ... IN BOOLEAN MODE ... ;
索引提示適用於 DELETE
陳述式,但僅限於使用多表 DELETE
語法時,如下所示
mysql> EXPLAIN DELETE FROM t1 USE INDEX(col2)
-> WHERE col1 BETWEEN 1 AND 100 AND COL2 BETWEEN 1 AND 100\G
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'use
index(col2) where col1 between 1 and 100 and col2 between 1 and 100' at line 1
mysql> EXPLAIN DELETE t1.* FROM t1 USE INDEX(col2)
-> WHERE col1 BETWEEN 1 AND 100 AND COL2 BETWEEN 1 AND 100\G
*************************** 1. row ***************************
id: 1
select_type: DELETE
table: t1
partitions: NULL
type: range
possible_keys: col2
key: col2
key_len: 5
ref: NULL
rows: 72
filtered: 11.11
Extra: Using where
1 row in set, 1 warning (0.00 sec)