쿼리 속도를 높이는 방법과 동시에 date/mktime 함수를 호출하는 데 필요한 오버 헤드를 최소화하는 방법에 대한 최적의 방법에 대한 조언을 찾고 있습니다.다른 반전으로 그룹화해야하는 쿼리에서로드를 최소화하는 방법은 무엇입니까?
CREATE TABLE my_table(
id INTEGER PRIMARY KEY NOT NULL AUTO_INCREMENT,
important_data INTEGER,
date INTEGER);
는 사용자가 1을 표시하도록 선택할 수 있습니다) 두 날짜 사이의 모든 항목 :
SELECT * FROM my_table
WHERE date >= ? AND date <= ?
ORDER BY date DESC;
출력 :
10-21-2009 12:12:12, 10002
10-21-2009 14:12:12, 15002
10-22-2009 14:05:01, 20030
10-23-2009 15:23:35, 300
....
나는 다음과 같은 테이블 레이아웃을 처리하고있어 문제를 사소하게하려면
이 경우 개선 할 점이 많지 않다고 생각합니다.
2) 하루 요약한다/그룹 출력, 주, 월, 년 : 월별로
SELECT COUNT(*) AS count, SUM(important_data) AS important_data
FROM my_table
WHERE date >= ? AND date <= ?
ORDER BY date DESC;
예 출력 :
10-2009, 100002
11-2009, 200030
12-2009, 3000
01-2010, 0 /* <- very important to show empty dates, with no entries in the table! */
....
나는 현재를 실행하는거야) 옵션 2를 달성하기 다음과 같은 mktime/date를위한 매우 비용이 많이 드는 for-loop :
for(...){ /* example for group by day */
$span_from = (int)mktime(0, 0, 0, date("m", $time_min), date("d", $time_min)+$i, date("Y", $time_min));
$span_to = (int)mktime(0, 0, 0, date("m", $time_min), date("d", $time_min)+$i+1, date("Y", $time_min));
$query = "..";
$output = date("m-d-y", ..);
}
지금까지 내 생각은 무엇입니까? 하루 (20091212), 월 (200912), 주 (200942) 및 연도 (2009)에 대한 추가/중복 열 (INTEGER)을 추가하십시오. 이렇게하면 for 루프에서 불필요한 쿼리를 모두 제거 할 수 있습니다. 그러나 나는 데이터베이스에서 동등한 가치가없는 모든 날짜를 매우 빨리 계산하기 위해 여전히 문제에 직면 해있다. 문제를 단순히 이동시키는 한 가지 방법은 MySQL이 작업을 수행하고 왼쪽 조인 (데이터)을 사용하여 간단한 쿼리 (모든 날짜 계산/MySQL 날짜 함수 사용)를 사용하는 것입니다. MySQL에 추가로드를 허용하는 것이 현명한 방법일까요? 어쨌든 for 루프에서 이러한 모든 mktime/date를 사용하기를 꺼립니다. 필자는 테이블 레이아웃과 코드를 완벽하게 제어 할 수 있으므로 주요 변경 사항을 제안해도 좋습니다. 그렉에
업데이트
덕분에 나는 다음과 같은 SQL 쿼리를 함께했다. 당신은 확실히 루프 내부 쿼리를 수행해서는 안
SELECT * FROM (
SELECT DATE_ADD('2009-01-30', INTERVAL 0 DAY) AS day UNION ALL
SELECT DATE_ADD('2009-01-30', INTERVAL 1 DAY) AS day UNION ALL
SELECT DATE_ADD('2009-01-30', INTERVAL 2 DAY) AS day UNION ALL
SELECT DATE_ADD('2009-01-30', INTERVAL 3 DAY) AS day UNION ALL
......
SELECT DATE_ADD('2009-01-30', INTERVAL 50 DAY) AS day) AS dates
LEFT JOIN (
SELECT DATE_FORMAT(date, '%Y-%m-%d') AS date, SUM(data) AS data
FROM test
GROUP BY date
) AS results
ON DATE_FORMAT(dates.day, '%Y-%m-%d') = results.date;
감사합니다! DATE_FORMAT를 성공적으로 사용하려면 INTEGER에서 DATETIME으로 전환해야하기 때문에 아이디어를 테스트하는 데 어느 정도 시간이 걸릴 것입니다. 그러나 그것은 유망 해 보인다. 한 가지가 누락되었다고 오인하지 않으면 테이블에 항목이없는 모든 날짜를 어떻게 얻습니까? 예 : 2009-10 및 2009-11에 대한 데이터가 있지만 2009-12는 비어 있지만 표시되어야합니다.내가 이것에 대한 PHP 기능으로 돌아 가야합니까 아니면 이것에 대한 우아한 mysql 솔루션이 있습니까? – merkuro
@merkuro : 거기에있는 데이터 만 출력 할 수 있습니다. 누락 된 레코드는 마술처럼 나타나지 않습니다. 만약 당신이 일년 중 매일 기록을 남기고 싶다면 캘린더 테이블을 만들고 그것에 대한 외부 조인을하십시오. 이러한 테이블은 한 번만 작성되고 채워질 필요가 있으며 연간 365 개의 행이 필요합니다. 이 방법으로 출력에서 "갭"이 사라집니다. – Tomalak
@Tomalak 당신은 MySQL 설치가 통합 된 마술사와 함께 오지 않는다는 것을 의미합니까? 솔직히, 무슨 목적으로 너의 snarky 코멘트가 있었나요? 왼쪽 결합을 사용하는 옵션에 대해서는 이미 언급했는데 디스크 사용량이 증가했기 때문에이 솔루션에서 잠재적 인 성능 문제가 있음을 알았습니다. 어쨌든 나는 누군가가 간과 한 기능과 같은 멋진 범위/배열을 생각해 내기를 바랐다. – merkuro