我有一张表有大量记录的帖子。我想今天向用户显示帖子,大概是3-4 k。
creation_date - Boolean
字段。该字段具有索引。
在我的查询中,我使用查询过滤简单记录:
DATETIME
此查询执行14秒。
然后我改为:
SELECT posts.title AS post_title
WHERE date(posts.creation_date) = DATE('2016-06-11')
这需要0.2秒......
为什么会这样?
我如何转换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
或MONTH(posts.creation_date)
,因为它们也会减慢查询速度,但我需要每月和每年显示帖子。
答案 0 :(得分:5)
在where子句中的字段上使用函数是一个非常糟糕的主意。当你这样做时,MySQL必须读取所有行(FULL TABLE SCAN)以查看函数后面的结果,并将其与常量进行比较。
使用常量部分的函数要好得多,它只转换一次,查询可以使用索引。
一天
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