Mysql

如果使用日期函式,在 MySQL 中索引日期列不起作用

  • August 29, 2020

我有一個具有以下架構的表

table_name

id int
task_id int
completed_date datetime (INDEX IX_TBL_NAME_COMPLETED_DATE)

我在這個查詢上執行 EXPLAIN

EXPLAIN 
   SELECT
       *
   FROM table_name TBL
   WHERE
       TBL.completed_date BETWEEN date1 AND date2

此查詢使用 completed_date 上的索引執行並獲取記錄

但是,在使用日期函式執行相同的查詢時

EXPLAIN 
   SELECT
       *
   FROM table_name TBL
   WHERE
       CONVERT_TZ(TBL.completed_date, timezone1, timezone2) BETWEEN date1 AND date2

未使用索引導致查詢緩慢。

有人可以解釋這種行為背後的原因和優化這樣的查詢的解決方案嗎?

這是任何類型的功能轉換的常見問題,不僅是日期。為了避免這個問題,只需將轉換移動到比較的常量側。代替

WHERE CONVERT_TZ(TBL.completed_date, timezone1, timezone2) 
     BETWEEN date1 
         AND date2

使用下一個語法:(注意 TZ 的反向轉換)

WHERE TBL.completed_date
     BETWEEN CONVERT_TZ( date1, timezone2 , timezone1 )
         AND CONVERT_TZ( date2, timezone2 , timezone1 )

這種行為的原因是普通索引包含自己排序的普通值。實現的功能索引mysql-8.0.13+可以儲存由某些功能排序的值。並且只有該函式可以在查找中被索引。有時不可能將泛函變換移到常數一側,因此泛函索引是唯一的選擇。

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