3

我有一个有很多行的表,所以当我进行这个查询时:

SELECT     
    date_trunc('hour', fecha) AS momento
    ,(extract(minute FROM fecha)::int / 5) AS min
    ,count(fecha) AS cuenta
FROM   table1
WHERE fk_id_busqueda=$id_busqueda 
GROUP  BY 1, 2
ORDER  BY 1, 2;

这需要很多时间。我正在考虑的一个解决方案是创建一个 postgres 函数,我可以在其中按日期对数据进行排序,然后每次对上一行的时刻求和一个,这与带有循环的实际时刻相同。何时不同,然后重置该值并传递到下一行。这个想法是该函数接收 id_busqueda (int)。

输出应该是这样的:

 2013-01-20 00:00:00 |         0 |    16
 2013-01-20 00:00:00 |         1 |    30
 2013-01-20 00:00:00 |         2 |    27
 2013-01-20 00:00:00 |         3 |    30
 2013-01-20 00:00:00 |         4 |    33
 2013-01-20 00:00:00 |         5 |    21
 2013-01-20 00:00:00 |         6 |    27
 2013-01-20 00:00:00 |         7 |    27
 2013-01-20 00:00:00 |         8 |    19
 2013-01-20 00:00:00 |         9 |    13
 2013-01-20 00:00:00 |        10 |    17
 2013-01-20 00:00:00 |        11 |    24
 2013-01-20 01:00:00 |         0 |    12
 2013-01-20 01:00:00 |         1 |    15
 2013-01-20 01:00:00 |         2 |    25
 2013-01-20 01:00:00 |         3 |    19
 2013-01-20 01:00:00 |         4 |    10
 2013-01-20 01:00:00 |         5 |    12
 2013-01-20 01:00:00 |         6 |    13
4

2 回答 2

2

除了在 fk_id_busqueda 列上创建索引之外,这应该会减少执行时间:

SELECT     
    date_trunc('minute', fecha) - 
    (extract(minute from fecha)::integer % 5) * interval '1 minute' as momento
    ,count(fecha) AS cuenta
FROM   table1
WHERE fk_id_busqueda=$id_busqueda 
GROUP  BY 1
ORDER  BY 1
于 2013-01-31T21:31:12.303 回答
1

我希望这个功能能完成任务。

create or replace function myfunc(id_busqueda integer)
returns table (momento timestamp, min int, cuenta int)
language plpgsql as $$
declare
    t record;
    momento timestamp;
    imomento timestamp;
    mins integer;
    imins integer;
    was boolean;
begin
    was := false;
    cuenta := 1;
    for t in 
        select fecha 
        from table1 
        where fk_id_busqueda = id_busqueda
        order by fecha
    loop
        momento := date_trunc('hour', t.fecha);
        mins := extract(minute FROM t.fecha)::int / 5;
        if imins = mins and imomento = momento then
            cuenta := cuenta+ 1;
        else
            if was then
                return query select imomento, imins, cuenta;
            end if;
            cuenta := 1;
            imins := mins;
            imomento := momento;
            was := true;
        end if;
    end loop;
    if was then
        return query select imomento, imins, cuenta;
    end if;
end; $$;
于 2013-01-31T21:19:57.110 回答