我必须每月获取记录/计数。 没有办法做——
1
SELECT COUNT(1)AS approved FROM lu_registration
WHERE MONTH(approved_date)=MONTH(NOW()) AND YEAR(approved_date)=YEAR(NOW());
2
SELECT COUNT(1)AS approved FROM lu_registration
WHERE DATE_FORMATE(approved_date, '%Y-%m')=DATE_FORMATE(NOW(), '%Y-%m');
3
SELECT COUNT(CASE WHEN MONTH(approved_date)=MONTH(NOW())
AND YEAR(approved_date)=YEAR(NOW()) THEN 1 END)AS approved FROM lu_registration;
4
SELECT COUNT(CASE WHEN DATE_FORMATE(approved_date, '%Y-%m')=DATE_FORMATE(NOW(), '%Y-%m')
THEN 1 END)AS approved FROM lu_registration;
哪一个最好。
实际塞内里奥: 有一个月份过滤器,我们通过它选择月份,并得到 04-2016。这样我们就可以使用 date_format (%m-%y) 或 Month=04 & Year=2016 来匹配获取记录。但哪个性能更好
实际要优化的查询是:
SELECT COUNT(CASE WHEN status='A' AND MONTH(approved_date)=04
AND YEAR(approved_date)=2016 THEN 1 END)AS approved, COUNT(CASE WHEN status='D' AND MONTH(reject_date)=04
AND YEAR(reject_date)=2016 THEN 1 END)AS rejected FROM lu_registration;
这里是approved_date和reject_date两个不同的列或者批准的用户也会被拒绝
最佳答案
您正在尝试对某个日期范围内的记录进行计数。恕我直言,您建议的查询都没有效率。没有人可以利用您的 approved_date
上的 MySQL 索引柱子。他们都不是sargeable.这会损害性能,尤其是当您的应用程序添加日期可追溯到几年前的记录时。
相反,您需要以下形式的查询
SELECT COUNT(*) AS approved
FROM table
WHERE approved_date >= <<<00:00 on first date>>>
AND approved_date < <<<00:00 on day after last date>>>
这可以做 index scan在approved_date列的索引上。
所以,现在需要的技巧是获取 <<<00:00 on first date>>
的正确值和<<<00:00 on day after last date>>>
来自NOW()
。这就是你要做的。
-
LAST_DAY(NOW())
给出本月最后一天的 00:00。 -
LAST_DAY(NOW()) + INTERVAL 1 DAY
给出下个月第一天的 00:00。 -
LAST_DAY(NOW()) + INTERVAL 1 DAY - INTERVAL 1 MONTH
给出当月第一天的 00:00。
因此,您的查询变为
SELECT COUNT(*) AS approved
FROM lu_registration
WHERE approved_date >= LAST_DAY(NOW()) + INTERVAL 1 DAY
AND approved_date < LAST_DAY(NOW()) + INTERVAL 1 DAY - INTERVAL 1 MONTH
它选择正确的日期范围,并且运行速度很快。
(请注意,我使用 COUNT(*)
代替了 COUNT(1)
。这是因为 COUNT(*)
是计数记录的常用方法。有时 RDMS 软件中的查询规划器模块会对其进行专门优化。)
关于mysql - DATE_FORMATE() 或 MONTH(),YEAR() 中哪一个更好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36644059/