MySQL 支援降序索引:索引定義中的 DESC
不再被忽略,而是會導致金鑰值以遞減順序儲存。先前,索引可以反向掃描,但效能會降低。降序索引可以正向掃描,這樣效率更高。當最有效率的掃描順序混合某些欄位的遞增順序和其他欄位的遞減順序時,降序索引也使最佳化工具能夠使用多欄索引。
考量下列資料表定義,其中包含兩個欄位和四個雙欄索引定義,用於欄位上遞增和遞減索引的各種組合
CREATE TABLE t (
c1 INT, c2 INT,
INDEX idx1 (c1 ASC, c2 ASC),
INDEX idx2 (c1 ASC, c2 DESC),
INDEX idx3 (c1 DESC, c2 ASC),
INDEX idx4 (c1 DESC, c2 DESC)
);
資料表定義會產生四個不同的索引。最佳化工具可以對每個 ORDER BY
子句執行正向索引掃描,而無需使用 filesort
操作
ORDER BY c1 ASC, c2 ASC -- optimizer can use idx1
ORDER BY c1 DESC, c2 DESC -- optimizer can use idx4
ORDER BY c1 ASC, c2 DESC -- optimizer can use idx2
ORDER BY c1 DESC, c2 ASC -- optimizer can use idx3
降序索引的使用受限於下列條件
降序索引僅支援
InnoDB
儲存引擎,並具有下列限制如果索引包含降序索引金鑰欄位,或主鍵包含降序索引欄位,則不支援對次要索引進行變更緩衝。
InnoDB
SQL 解析器不使用降序索引。對於InnoDB
全文搜尋,這表示索引資料表的FTS_DOC_ID
欄位上需要的索引無法定義為降序索引。如需更多資訊,請參閱 第 17.6.2.4 節「InnoDB 全文索引」。
降序索引支援所有可用於遞增索引的資料類型。
降序索引支援普通 (非產生) 和產生欄位 (包括
VIRTUAL
和STORED
)。DISTINCT
可以使用任何包含相符欄位的索引,包括降序金鑰部分。降序索引支援
BTREE
但不支援HASH
索引。不支援FULLTEXT
或SPATIAL
索引的降序索引。為
HASH
、FULLTEXT
和SPATIAL
索引明確指定的ASC
和DESC
指示器會導致錯誤。
您可以在 EXPLAIN
輸出的 Extra
欄位中看到,最佳化工具能夠使用降序索引,如下所示
mysql> CREATE TABLE t1 (
-> a INT,
-> b INT,
-> INDEX a_desc_b_asc (a DESC, b ASC)
-> );
mysql> EXPLAIN SELECT * FROM t1 ORDER BY a ASC\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t1
partitions: NULL
type: index
possible_keys: NULL
key: a_desc_b_asc
key_len: 10
ref: NULL
rows: 1
filtered: 100.00
Extra: Backward index scan; Using index
在 EXPLAIN FORMAT=TREE
輸出中,使用降序索引會透過在索引名稱後方加上 (reverse)
來表示,如下所示
mysql> EXPLAIN FORMAT=TREE SELECT * FROM t1 ORDER BY a ASC\G
*************************** 1. row ***************************
EXPLAIN: -> Index scan on t1 using a_desc_b_asc (reverse) (cost=0.35 rows=1)
另請參閱 EXPLAIN 額外資訊。