2016-04-15 115 views
1

我必須每月獲得記錄/計數。 沒有方法可以做到---哪一個更好從DATE_FORMATE()或MONTH(),YEAR()

SELECT COUNT(1)AS approved FROM lu_registration 
WHERE MONTH(approved_date)=MONTH(NOW()) AND YEAR(approved_date)=YEAR(NOW()); 
SELECT COUNT(1)AS approved FROM lu_registration 
WHERE DATE_FORMATE(approved_date, '%Y-%m')=DATE_FORMATE(NOW(), '%Y-%m'); 
SELECT COUNT(CASE WHEN MONTH(approved_date)=MONTH(NOW()) 
AND YEAR(approved_date)=YEAR(NOW()) THEN 1 END)AS approved FROM lu_registration; 
​​

哪一個最好。

當前Senerio: 有一個月過濾器,我們選擇月,得到04-2016。這樣我們就可以使用DATE_FORMAT(%間%Y)或月= 04 &年= 2016匹配得到records.but哪一個性能更好的明智

實際查詢優化是:

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兩個不同的列或已批准的用戶也可以拒絕

回答

0

我覺得第一個是Better--

SELECT COUNT(1)AS approved FROM lu_registration 
WHERE MONTH(approved_date)=MONTH(NOW()) AND YEAR(approved_date)=YEAR(NOW()); 
2

您正在嘗試對日期範圍內的記錄進行計數。請注意,您的建議查詢都不是有效的。沒有人可以利用您的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>>> 

這可以在你的approved_date列的索引做一個index scan的查詢。

所以,現在需要的技巧是從NOW()獲取<<<00:00 on first date>><<<00:00 on day after last date>>>的正確值。這就是你所做的。

  1. LAST_DAY(NOW())在本月的最後一天給出00:00。
  2. LAST_DAY(NOW()) + INTERVAL 1 DAY在下個月的第一天給出00:00。
  3. 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軟件中的查詢規劃模塊會對其進行優化。)

+0

好的答案,很好的解釋,加上我學到了一個新單詞!謝謝! :-) – PerlDuck

+0

有一個月份過濾器,我們選擇月份,並檢索爲04-2016。因此,我們可以使用date_format(%m-%y)或month = 04&year = 2016來獲取記錄。但哪一個性能更好? – Zigri2612

+0

@ Zigri2612 - 一個範圍(可以使用索引)始終優於任何種表達。 –

相關問題