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

标签 mysql sql date datetime

我有一张 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/

相关文章:

mysql - mysql 中修改表的替代方案

mysql - 将 select 语句转换为 Group by

php - 尝试将 mysql select 语句转换为 PDO

JavaScript new Date(dateStr) 以特定格式给出昨天的日期

java - 在单独的线程中运行每个 SQL 查询(在启动期间)是一种不好的做法吗?

mysql - 多列范围

php - Mysql 存储大量位大小的设置

sql - MAX加上其他数据通过JOIN

php - 如何更改日期格式? (YII)

PHP 查找最小数字/日期的快捷方式