모든 세부 행을 가져오고 클라이언트 측에서 카운트하는 것이 아니라 데이터베이스가 카운트를 반환하도록하는 것이 훨씬 빠릅니다.
그리고 하나의 쿼리에서 전체 24 시간 동안 카운트를 가져올 수 있습니다. 개별 카운트를 얻기 위해 데이터베이스를 24 라운드 왕복하는 것보다 훨씬 효율적입니다.
인덱스가 c_blacklist(timestamp)
이상이거나 c_blacklist(timestamp,reason)
의 커버 인덱스 인 경우 쿼리 성능이 향상 될 가능성이 높습니다.
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')
이 쿼리가있다 "격차"가됩니다 계산할 행이 없습니다. 즉, 0의 수를 리턴하지 않습니다.
"시간"에 대한 각 값을 반환하는 행 원본을 제공 한 다음 결과 집합을 사용하여 왼쪽 조인을 수행하면 해결할 수 있습니다. 다음 명령문에서 h로 별명이 지정된 부속 조회는 시간당 하나씩 24 행을 리턴합니다. 우리는 "결과"쿼리 (위의)에 대한 왼쪽 조인의 구동 행 소스로이를 사용합니다. 우리가 일치하지 않는 곳이라면, 카운트에 대해 NULL을 얻습니다. 그리고 우리는 NULL을 0으로 간단하게 함수 호출로 대체 할 수 있습니다.
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'입니까? timestamp 열의 WHERE 절이 최적보다 적을 수 있습니다. – spencer7593