2012-05-28 1 views
0
SELECT CASE WHEN avg(count)>12 THEN 5 
      WHEN avg(count)>8 THEN 4 
      WHEN avg(count)>2 THEN 3 
      WHEN avg(count)>1 THEN 2 
      ELSE 1 
      END,madeby 
FROM (SELECT M.month,(SELECT count(*) 
        FROM Booking 
        WHERE date_trunc('month',starttime)=month 
         AND madeby=M.madeby 
        ) AS count,M.madeby 
    FROM (SELECT date_trunc('month',generate_series(min(starttime), 
          current_timestamp,interval '1 month')::timestamp) 
          AS month,madeby 
      FROM Booking 
      GROUP BY madeby 
    ) AS M 
) AS BookingsPerMonth 
GROUP BY madeby; 

Теперь мне нужно сделать это вычисление, я не спрашиваю об этом. Я предполагаю, что проблема заключается в том, что он вычисляет совокупную функцию avg четыре раза. Разница во времени составляет от ~ 17 секунд с CASE до ~ 4,5 секунд без (хотя у меня тогда не хватает достаточной информации)CASE с совокупными функциями, значительно замедляющими запрос, лучший способ?

Есть ли способ, который я могу оптимизировать, используя переменную память или что-то в этом роде, чтобы привести время ближе к 4,5 секунды?

ответ

2
SELECT 
    CASE 
     WHEN avg_count > 12 THEN 5 
     WHEN avg_count > 8 THEN 4 
     WHEN avg_count > 2 THEN 3 
     WHEN avg_count > 1 THEN 2 
     ELSE 1 
    END, 
    madeby 
FROM (
    SELECT avg(count) as avg_count, madeby 
    FROM (
     SELECT 
      M.month, 
      (
       SELECT count(*) 
       FROM Booking 
       WHERE date_trunc('month',starttime)=month AND madeby=M.madeby 
      ) AS count, 
      M.madeby 
     FROM (
      SELECT 
       date_trunc('month',generate_series(min(starttime), 
       current_timestamp,interval '1 month')::timestamp) AS month, 
       madeby 
      FROM Booking 
      GROUP BY madeby 
     ) AS M 
    ) AS BookingsPerMonth 
    GROUP BY madeby 
) AS Averages; 
+0

Назад прямо к ~ 4,5 - спасибо дружище. Удивлен, что после выполнения всего запроса я не мог думать об этом = .- Надеюсь на какое-то странное переменное решение, но это хорошо –

0

Я хотел бы попробовать, чтобы PG calculcate в СРЕДНЕМ только один раз, как это (из головы):

Вместо делать

SELECT CASE WHEN avg(count)>12 THEN 5 
      WHEN avg(count)>8 THEN 4 
... 

сделать

SELECT CASE WHEN avgcount>12 THEN 5 
      WHEN avgcount>8 THEN 4 
... 

и затем заменить

FROM (SELECT M.month,(SELECT count(*) 
... 
        ) AS count,M.madeby 

с

FROM (SELECT avg(M.month),(SELECT count(*) 
... 
        ) AS avgcount,M.madeby 

С уважением, С.