DATE()MONTH()等函数减慢查询速度

Art*_*rti 2 mysql sql datetime date

我有一个表中有很多记录的帖子。我想向用户显示今天的帖子,大约3-4 k。

CREATION_DATE - DATETIME场。该字段具有索引。

在我的查询中,我使用查询简单过滤记录:

 SELECT posts.title AS post_title
 WHERE date(posts.creation_date) = DATE('2016-06-11')
Run Code Online (Sandbox Code Playgroud)

该查询执行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
Run Code Online (Sandbox Code Playgroud)

而且需要0.2秒...

为什么会这样呢?以及如何转换MONTH(posts.creation_date)YEAR(posts.creation_date)因为它们也会减慢查询速度,但我需要每月和每年的展示帖子。

Ber*_*fen 5

在where子句中的字段上使用函数是一个非常糟糕的主意。当您这样做时,MySQL必须读取所有行(FULL TABLE SCAN)以查看该函数之后的结果,并将其与常量进行比较。

在常量部分使用函数要好得多,它只能转换一次并且查询可以使用索引。

仅一天

SELECT ... WHERE datetimefield between '2016-01-05 00:00:00' AND '2016-01-05 23:59:59';
Run Code Online (Sandbox Code Playgroud)

要么

SELECT ... WHERE datetimefield between '2016-01-05 00:00:00' AND '2016-01-05 00:00:00' + INTERVAL 1 DAY
Run Code Online (Sandbox Code Playgroud)

一个月

SELECT ... WHERE datetimefield between '2016-06-01 00:00:00' AND '2016-06-01 00:00:00' + INTERVAL 1 MONTH;
Run Code Online (Sandbox Code Playgroud)

您可以在执行计划中查看查询的工作:

EXPLAIN SELECT posts.title AS post_title
 WHERE date(posts.creation_date) = DATE('2016-06-11');
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)