Shy*_*haa 2 mysql optimization index-tuning datetime mysql-5.7
我有一个具有以下架构的表
table_name
id int
task_id int
completed_date datetime (INDEX IX_TBL_NAME_COMPLETED_DATE)
Run Code Online (Sandbox Code Playgroud)
我在这个查询上运行 EXPLAIN
EXPLAIN
SELECT
*
FROM table_name TBL
WHERE
TBL.completed_date BETWEEN date1 AND date2
Run Code Online (Sandbox Code Playgroud)
此查询使用已完成日期的索引运行并获取记录
但是,在使用日期函数运行相同的查询时
EXPLAIN
SELECT
*
FROM table_name TBL
WHERE
CONVERT_TZ(TBL.completed_date, timezone1, timezone2) BETWEEN date1 AND date2
Run Code Online (Sandbox Code Playgroud)
未使用索引导致查询变慢。
有人可以解释这种行为背后的原因以及优化此类查询的解决方案吗?
这是任何类型的函数转换的常见问题,不仅仅是日期。为了避免这个问题,只需将转换移动到比较的常量侧即可。代替
WHERE CONVERT_TZ(TBL.completed_date, timezone1, timezone2)
BETWEEN date1
AND date2
Run Code Online (Sandbox Code Playgroud)
使用下一个语法:(注意 TZ 的反向转换)
WHERE TBL.completed_date
BETWEEN CONVERT_TZ( date1, timezone2 , timezone1 )
AND CONVERT_TZ( date2, timezone2 , timezone1 )
Run Code Online (Sandbox Code Playgroud)
这种行为的原因是普通索引包含自己排序的普通值。中实现的功能索引mysql-8.0.13+
可以存储由某个函数排序的值。并且只有该函数可以在查找时建立索引。有时无法将函数变换移到常数侧,因此函数索引是唯一的选择。