2010-07-01 8 views
5

de alto nivel: ¿Puedo hacer esto order by, group by basa en sum más rápido? (Pág. 8.4, fwiw, en una pequeña mesa no pensar .... O (millones de filas))mejora del algoritmo en una simple consulta PostgreSQL mirando

Supongamos que tenía una tabla como la siguiente:

        Table "public.summary" 
    Column |  Type  |      Modifiers 
-------------+-------------------+------------------------------------------------------ 
ts   | integer   | not null default nextval('summary_ts_seq'::regclass) 
field1  | character varying | not null 
otherfield | character varying | not null 
country  | character varying | not null 
lookups  | integer   | not null 


Indexes: 
    "summary_pk" PRIMARY KEY, btree (ts, field1, otherfield, country) 
    "ix_summary_country" btree (country) 
    "ix_summary_field1" btree (field1) 
    "ix_summary_otherfield" btree (otherfield) 
    "ix_summary_ts" btree (ts) 

Y la pregunta que quiero es :

select summary.field1, 
    summary.country, 
    summary.ts, 
    sum(summary.lookups) as lookups, 
from summary 
where summary.country = 'za' and 
    summary.ts = 1275177600 
group by summary.field1, summary.country, summary.ts 
order by summary.ts, lookups desc, summary.field1 
limit 100; 

(Inglés: top 100 de campo1 en una determinada dirección (ts, país), donde 'topness' es la suma de operaciones de búsqueda para cualquier fila coincidente, sin importar el valor de otherfield)

¿hay cualquier cosa Realmente puedo hacer para acelerar esto? Algorítmicamente esto parece ser una exploración de tabla completa, pero me podría estar perdiendo algo.

+0

+1: ¡Bien formateado, y usa una secuencia para poblar el pk! –

+1

'LIMIT 100 'significa que solo se devolverán 100 filas, no las 100 principales para cada ts/país/etc. –

+0

Consejo de formato para SO, recuerde ponerlo todo en minúsculas, por extraño que parezca :) –

Respuesta

1

Para poder sugerir algo, debe publicar el plan de ejecución de la consulta.

Y "OMG Ponies" tiene razón: el límite 100 limitará el resultado general a 100 filas, ¡no funcionará en grupos individuales!

Hay un buen artículo en el Postgres Wiki que explica cómo publicar una pregunta relacionada con una consulta lenta:

http://wiki.postgresql.org/wiki/SlowQueryQuestions

+0

He corregido la pregunta para reflejar el punto de OMG Ponies. Son correctos, pero esta es la consulta correcta y lo que quiero. He actualizado el texto para que coincida. –

2

Cualquier plan de consulta para esta consulta tendrá que escanear cada fila que coincide con el DONDE las condiciones, desplegándolas según las condiciones de agrupación, es decir, la cantidad de trabajo es proporcional al número de filas de entrada al grupo, no a la cantidad de filas de resultados.

El plan de consulta más eficiente posible para una consulta como esta es una exploración de índice único. Esto debería ser posible si crea un índice en (país, ts) en ese orden; con ese índice, cada consulta posible de este formulario se resuelve en un rango contiguo sobre el índice. Sin embargo, esto aún requerirá un ordenamiento en memoria: es posible evitar esto con un índice diferente.

Como han dicho otros, publicar su plan de ejecución es su mejor opción.

1

El índice en (país, ts) es una mejor opción (como sugiere Nick Johnson), y, además, es posible que desee aumentar work_mem si no está configurado muy alto. Puede ESTABLECER esto en tiempo de ejecución si es necesario (y si lo hace muy alto, entonces recomendado). Te ayudará a mantener tus géneros en la memoria y no a derramar en el disco (si eso sucede).

Para obtener ayuda, necesitaremos ver un EXPLAIN ANALYZE, publicarlo en explain.depesz.com puede hacerlo muy legible.

Cuestiones relacionadas