我有一张 Posts 表,里面有很多记录。我想给用户显示今天的帖子,大约是 3-4 k。
creation_date - DATETIME
字段。该字段有索引。
在我的查询中,我用查询简单地过滤了记录:
SELECT posts.title AS post_title
WHERE date(posts.creation_date) = DATE('2016-06-11')
此查询执行 14 秒。
然后我把它改成了:
SELECT posts.title AS post_title
WHERE pending_posts.creation_date > CONVERT('2016-06-11', DATETIME)
AND pending_posts.creation_date < CONVERT('2016-06-11', DATETIME) + INTERVAL 1 DAY
它需要 0.2 秒...
为什么会这样?
我如何转换 MONTH(posts.creation_date)
或 YEAR(posts.creation_date)
因为它们也会减慢查询速度,但我需要每月和每年显示帖子。
最佳答案
在 where 子句中的字段上使用函数是一个非常糟糕的主意。当你这样做时,MySQL 必须读取所有行(全表扫描)以查看函数之后的结果是什么,并将其与常量进行比较。
在常量部分使用函数要好得多,因为它只转换一次并且查询可以使用索引。
一天
SELECT ... WHERE datetimefield between '2016-01-05 00:00:00' AND '2016-01-05 23:59:59';
或
SELECT ... WHERE datetimefield between '2016-01-05 00:00:00' AND '2016-01-05 00:00:00' + INTERVAL 1 DAY
一个月
SELECT ... WHERE datetimefield between '2016-06-01 00:00:00' AND '2016-06-01 00:00:00' + INTERVAL 1 MONTH;
您可以在执行计划中看到查询的工作:
EXPLAIN SELECT posts.title AS post_title
WHERE date(posts.creation_date) = DATE('2016-06-11');
和
EXPLAIN SELECT posts.title AS post_title
WHERE pending_posts.creation_date > CONVERT('2016-06-11', DATETIME)
AND pending_posts.creation_date < CONVERT('2016-06-11', DATETIME) + INTERVAL 1 DAY
关于mysql - DATE() MONTH() 等函数减慢查询速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37777883/