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


MySQL 8.4 參考手冊  /  ...  /  降序索引

10.3.13 降序索引

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 全文索引」

  • 降序索引支援所有可用於遞增索引的資料類型。

  • 降序索引支援普通 (非產生) 和產生欄位 (包括 VIRTUALSTORED)。

  • DISTINCT 可以使用任何包含相符欄位的索引,包括降序金鑰部分。

  • 具有降序金鑰部分的索引不適用於呼叫彙總函數但沒有 GROUP BY 子句的查詢的 MIN()/MAX() 最佳化。

  • 降序索引支援 BTREE 但不支援 HASH 索引。不支援 FULLTEXTSPATIAL 索引的降序索引。

    HASHFULLTEXTSPATIAL 索引明確指定的 ASCDESC 指示器會導致錯誤。

您可以在 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 額外資訊