[Pgsql-ayuda] Maximo

Alvaro Herrera alvherre@dcc.uchile.cl
Sun, 23 Nov 2003 17:57:35 -0300


On Sun, Nov 23, 2003 at 03:11:27PM -0300, Haroldo Stenger wrote:

Haroldo,

> On Sun, 2003-11-23 at 12:53, Alvaro Herrera wrote:
> > ¿Qué tal las Jornadas de Software Libre?
> 
> Se realizaron, en general salieron bien.

Excelente.

> >  No vi a Justin
> > en el programa ... !?
> 
> No vino :-( y PostgreSQL quedo sin representante oficial. Una pena. 

Doh ... que lástima.

> [plan de ejecución]
> hay algunos seqscans, no se como interpretarlos, si es "eficiente", o
> no.

Hum.  Dos seqscans a la misma tabla.  Muy posiblemente hay alguna manera
de hacerlo más eficiente.

> hmmmm, self join es cuando pones una misma tabla mas de una vez en from
> ?

Sí.  Es un truco muy útil, aunque no sé si es aplicable aquí.


> > Hmm... yo tengo un sistema que usa harto SQL complejo, pero creo que es
> > demasiado específico para servir de ejemplo general :-(
> > Lo malo es que el sistema genera parte de las consultas al vuelo, así
> > que extraerlas del código es difícil ...
> 
> interesante! que hace tu sistema?

Calcula estadísticas y genera gráficos a partir de series temporales de
datos.  Es el lado de generación de reportes agregados de un sistema de
adquisición de datos; los datos provienen de varias fuentes y tienen
formas distintas dependiendo del objeto del que se trate.  La idea es
que el sistema tiene la menor cantidad de código repetido posible, por
lo que los nombres de tablas y columnas (y a veces las condiciones
WHERE) dependen del tipo de objeto de que se trata.

Un ejemplo.  El sistema entrega reportes mensuales.  El problema es que
a veces hay que generar un reporte a mitad de mes, y tiene que incluir
de qué porcentaje del mes no se conocen datos porque aún no haya
transcurrido.  Además se debe sumar el porcentaje de datos que no se
obtuvieron porque se haya empezado la adquisición después del principio
del mes; y además, el tiempo que no se conoce porque el computador que
hace la adquisición estuvo fuera de línea (es poco común pero sucede).
El SQL que hace todo eso es de como 30 líneas ...

SELECT EXTRACT(epoch FROM inicio-$inicio) /
    EXTRACT(epoch FROM $ticksPerSlot * $tickDuration)
FROM intervalos($inicio, $inicio + $timespan, $ticksPerSlot * $tickDuration)
        AS foo(inicio timestamptz, final timestamptz)
    JOIN $tablaEventos ON (foo.inicio >= date AND foo.final <= date+$duracion)
WHERE obj_id=$objId AND
    (date, date+$duracion) OVERLAPS ($inicio, $inicio+$timespan) AND $status=5
GROUP BY inicio HAVING count(servidor_id) = $mons
UNION
SELECT EXTRACT(epoch FROM inicio-$inicio) /
    EXTRACT(epoch FROM $ticksPerSlot * $tickDuration)
FROM intervalos($inicio, $inicio + $timespan, $ticksPerSlot * $tickDuration)
        AS foo(inicio timestamptz, final timestamptz)
WHERE final < (
    SELECT date
    FROM $tablaDatos
    WHERE obj_id=$objId AND
        date > $inicio
    ORDER BY obj_id, date
    LIMIT 1
)
UNION
SELECT EXTRACT(epoch FROM inicio-$inicio) /
    EXTRACT(epoch FROM $ticksPerSlot * $tickDuration)
FROM intervalos($inicio, $inicio + $timespan, $ticksPerSlot * $tickDuration)
        AS foo(inicio timestamptz, final timestamptz)
WHERE inicio > (
    SELECT date
    FROM $tablaDatos
    WHERE obj_id=$objId AND
        date < $inicio+$timespan
    ORDER BY obj_id DESC, date DESC
    LIMIT 1
)

-- 
Alvaro Herrera (<alvherre[a]dcc.uchile.cl>)
"No reniegues de lo que alguna vez creíste"