它會快很多有數據庫回報,你的計數,而不是拉回所有的細節行,這樣在客戶端的數量。
您可以在一個查詢中將整個24小時內的計數拉到一個查詢中,這將有可能比進行24次往返數據庫以獲得單個計數更有效。
如果您有c_blacklist(timestamp)
或更好的索引c_blacklist(timestamp,reason)
的覆蓋索引,那麼性能(查詢的)也可能會得到改進。
如果timestamp
列的數據類型爲TIMESTAMP
,那麼我們可以通過一些簡單的算術來導出「小時」,並按每個「小時」計算一次。
SELECT FROM_UNIXTIME((UNIX_TIMESTAMP(cb.`timestamp`) DIV 3600) * 3600) AS `cb_hour`
, COUNT(1) AS cb_count
FROM `c_blacklist` cb
WHERE cb.`timestamp` >= DATE_ADD('2012-06-26 18:00',INTERVAL -1 DAY)
AND cb.`timestamp` < '2012-06-26 18:00'
AND cb.`reason` = 'hardbounce'
GROUP BY FROM_UNIXTIME((UNIX_TIMESTAMP(cb.`timestamp`) DIV 3600) * 3600)
ORDER BY FROM_UNIXTIME((UNIX_TIMESTAMP(cb.`timestamp`) DIV 3600) * 3600)
如果時間戳列的數據類型DATETIME
的,它可能會更快使用不同的表達,以獲得時間:
SELECT DATE_FORMAT(cb.`timestamp`,'%Y-%m-%d %H:00:00') AS `cb_hour`
, COUNT(1) AS cb_count
FROM `c_blacklist` cb
WHERE cb.`timestamp` >= DATE_ADD('2012-06-26 18:00',INTERVAL -1 DAY)
AND cb.`timestamp` < '2012-06-26 18:00'
GROUP BY DATE_FORMAT(cb.`timestamp`,'%Y-%m-%d %H:00:00')
ORDER BY DATE_FORMAT(cb.`timestamp`,'%Y-%m-%d %H:00:00')
這個查詢將有「差距」那裏有沒有要計數的行,也就是說,它們不會返回零計數。
可以通過提供一個返回「hour」每個值的行源,然後執行結果集的左連接來解決這個問題。在下面的語句中,子查詢別名爲h返回24行,每個小時一個。我們使用它作爲左連接的驅動行源,以針對「結果」查詢(從上面)。任何我們沒有得到匹配的地方,我們都會得到一個NULL值。我們可以用一個簡單的函數調用將零替換爲零。
SELECT h.hour AS cb_hour
, IFNULL(c.cb_count,0) AS cb_count
FROM (SELECT DATE_ADD('2012-06-26 18:00',INTERVAL -1*d.i HOUR) AS `hour`
FROM (SELECT 00 AS i UNION ALL SELECT 01 UNION ALL SELECT 02 UNION ALL SELECT 03
UNION ALL SELECT 04 UNION ALL SELECT 05 UNION ALL SELECT 06 UNION ALL SELECT 07
UNION ALL SELECT 08 UNION ALL SELECT 09 UNION ALL SELECT 10 UNION ALL SELECT 11
UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15
UNION ALL SELECT 16 UNION ALL SELECT 17 UNION ALL SELECT 18 UNION ALL SELECT 19
UNION ALL SELECT 20 UNION ALL SELECT 21 UNION ALL SELECT 22 UNION ALL SELECT 23
ORDER BY 1 DESC
) d
) h
LEFT
JOIN (SELECT FROM_UNIXTIME((UNIX_TIMESTAMP(cb.`timestamp`) DIV 3600) * 3600) AS `cb_hour`
, COUNT(1) AS cb_count
FROM `c_blacklist` cb
WHERE cb.`timestamp` >= DATE_ADD('2012-06-26 18:00',INTERVAL -1 DAY)
AND cb.`timestamp` < '2012-06-26 18:00'
AND cb.`reason` = 'hardbounce'
GROUP BY FROM_UNIXTIME((UNIX_TIMESTAMP(cb.`timestamp`) DIV 3600) * 3600)
ORDER BY FROM_UNIXTIME((UNIX_TIMESTAMP(cb.`timestamp`) DIV 3600) * 3600)
) c
ON c.cb_hour = h.hour
ORDER BY h.hour
當然,這比現在有更多的查詢文本。
爲了讓我的代碼,我會用'%s'替換三次出現的日期文字,並使用sprintf用格式化的日期字符串替換三次出現。 (所有三次出現都通過相同的值。)
你可以做GROUP BY HOUR(FROM_UNIXTIME(unixtime))WHERE date = DATE(FROM_UNIXTIME(unixtime))嗎? – Kermit
「c_blacklist」中名爲'timestamp'的列的數據類型是什麼?它是'TIMESTAMP'還是它是'DATETIME'?時間戳列上的WHERE子句可能不太理想。 – spencer7593