2015-06-10 72 views
9

我有一個MySQL數據庫表有多個日期類型字段。我需要在此表上執行不同的SELECT查詢,但我不確定哪種方式最好從同一月份查找記錄。高效的SELECT查詢在一個月內找到記錄

我知道我能做到以下幾點:

SELECT * 
    FROM table 
WHERE MONTH(somedate) = 5 
    AND YEAR(somedate) = 2015 

但我繼續讀這是沒有效率的,我應該用實際日期去,即

SELECT * 
    FROM table 
WHERE somedate BETWEEN '2015-05-01' AND '2015-05-31' 

然而,所有我本來是PHP和PHP的變量來月份和年份。如果我使用第二個選項,我如何輕鬆快速地計算每月的最後一天?

+0

我發現'之間'比'month/year'慢,'like',在我的db上。月/年='顯示行0 - 29(共77個,查詢花費0.0825秒)'。在='顯示行0 - 29(共77個,查詢佔用0.1059秒)'之間。 Like ='顯示第0 - 29行(共77個查詢,0.0815秒)'。這是在一個7K的排桌子上。這個線程指向了另一個方向。 http://dba.stackexchange.com/questions/96245/mysql-date-field-filter-by-like-vs-month – chris85

+0

MySQL可以有效地使用「somedate」前導列的索引。如果你沒有這樣的索引,那麼你可以創建一個例如'CREATE INDEX ON table(somedate)'。只要查詢返回的表少於10%的行,索引將使查詢快得多。隨着圍繞somedate列的函數,MySQL必須在表中的每一行上評估這些函數。 – spencer7593

+0

使用'EXPLAIN'來查看執行計劃。爲了進行性能比較,請確保查詢緩存中沒有返回查詢結果。有幾種方法可以做到這一點,例如'SQL_NO_CACHE'命中,在查詢中包含用戶定義的變量,禁用查詢緩存等。(我們實際上已經配置了我們的MySQL服務器來緩存包含'SQL_CACHE'提示的查詢* ,所以我們控制哪些查詢可以被緩存,並防止結果被我們不需要緩存的查詢沖掉。) – spencer7593

回答

9

不計算該月的最後一天。請計算下個月的第一天。

您的查詢,可就是這樣

WHERE t.mydatetimecol >= '2015-05-01' 
    AND t.mydatetimecol < '2015-05-01' + INTERVAL 1 MONTH 

需要注意的是,我們正在做一個小於比較,而不是一個「小於或等於」 ......這是比較TIMESTAMP非常方便, DATETIME列,可包含時間部分。

請注意,BETWEEN比較是「小於或等於」。爲了得到一個比較等效於上面的查詢,我們需要做的

WHERE t.mydatetimecol 
     BETWEEN '2015-05-01' AND '2015-05-01' + INTERVAL 1 MONTH + INTERVAL -1 SECOND 

(這是假設的DATETIMETIMESTAMP分辨率降至第二。在其他的數據庫,如SQL Server,該決議比一秒鐘要好,所以我們有可能會錯過價值'2015-05-31 23:59:59.997'的行。我們沒有像第一天那樣的問題下個月的比較...... < '2015-06-01'

不需要自己做月份或日期數據,讓MySQL爲你做,如果你在月份中加1,你必須處理從12月到一月,和增值今年。 MySQL已經包含了所有的內容。

+0

不錯的工作斯賓塞 – AsConfused

3

date('t', strtotime("$year-$month-01"))會給天在一個月

+2

這是一個性能問題,而不是一個如何去做的問題。 – chris85

+0

這個特定任務的「如何做」問題在最後被問到。我認爲BETWEEN會是一個更好的表演者,如果其他人先不瞭解,可能會在後面詳細闡述。 –

相關問題