Mysql

使用具有日期範圍的複合索引

  • December 7, 2018

我有一張根據日期啟動的規則表。

id - name - value - start_date - end_date
1  - ABC  - 10    - 2015-12-01 - 2015-12-31
2  - DEF  - 15    - 2016-02-01 - 2016-02-29

我的 SQL 查詢主要是

SELECT * FROM rules WHERE start_date <= '2015-12-05' and end_date >= '2015-12-05';

start_date有一個由和組成的複合索引是否end_date有助於或會惡化查詢?

編輯:我正在使用 MySQL

很難判斷這是否會損害或提高性能,但添加複合索引start_date並且end_date不應該惡化您的查詢,索引將被使用或不使用。您沒有提到您的 RDBMS,但我認為您的引擎優化器選擇更差計劃的可能性不大(但我猜總是有可能)。

話雖如此,由於優化器需要考慮額外的索引,因此可能會對計劃生成時間產生輕微影響,並且未使用的索引可能會損害整體性能,因為在更新/插入時需要對其進行維護。

很難說索引是否會幫助您的查詢,這取決於您的查詢和基數統計的選擇性。RDBMS 的優化器應該選擇最快的方式來獲取數據,即使查詢在全掃描時選擇的列上存在索引也可能是更好的選擇,尤其是當您選擇所有欄位時。

為什麼選擇性很重要?

使用索引時,索引指向實際記錄,並且可能需要使用指針獲取記錄。大多數 RDBMS 都是這樣工作的。

參見例如Oracle 文件

一般來說,索引訪問路徑應該用於檢索一小部分錶行的語句,而全掃描在訪問大部分錶時效率更高

SQL Server 文件

在許多情況下,優化器強制對結果集約為 5% 的查詢進行表掃描,儘管在選擇性為 8% 到 10% 時表掃描比索引訪問更有效。

為什麼選擇 * 很重要

如果您從表中獲取所有欄位,您的數據庫引擎將不得不使用儲存在索引中的指針獲取實際記錄,並且您將失去使用included columns(如果您的 RDBMS 支持它們)或covering indexes.

例如,請參閱 SQL 伺服器的這篇文章(但原理適用於許多供應商):使用覆蓋索引來提高查詢性能

但是,在某些情況下,查詢優化器可能認為與非聚集索引相關的成本太大,SQL Server 將求助於表掃描來解決查詢。

觀察到的改進是由於非聚集索引包含解析查詢所需的所有資訊。不需要密鑰查找。

引用自:https://dba.stackexchange.com/questions/122533