Estoy usando postgres 9.4.
El messages
tiene el siguiente esquema: los mensajes mostrados pertenecen a FEED_ID, y tiene posted_at, también los mensajes pueden tener un mensaje de los padres (en caso de respuestas).
Table "public.messages"
Column | Type | Modifiers
------------------------------+-----------------------------+-----------
message_id | character varying(255) | not null
feed_id | integer |
parent_id | character varying(255) |
posted_at | timestamp without time zone |
share_count | integer |
Indexes:
"messages_pkey" PRIMARY KEY, btree (message_id)
"index_messages_on_feed_id_posted_at" btree (feed_id, posted_at DESC NULLS LAST)
Quiero devolver todos los mensajes ordenados por share_count
, pero para cada uno parent_id
, solo quiero devolver un mensaje. es decir, si varios mensajes tienen lo mismo parent_id
, solo posted_at
se devuelve el último ( ). El parent_id
puede ser nulo, los mensajes con nula parent_id
debe toda la vuelta.
La consulta que utilicé es:
WITH filtered_messages AS (SELECT *
FROM messages
WHERE feed_id IN (7)
AND (posted_at >= '2015-01-01 04:00:00.000000')
AND (posted_at < '2015-04-28 04:00:00.000000'))
SELECT *
FROM (SELECT DISTINCT ON(COALESCE(parent_id, message_id)) parent_id,
message_id,
posted_at,
share_count
FROM filtered_messages
ORDER BY COALESCE(parent_id, message_id), posted_at DESC NULLS LAST
) messages
ORDER BY share_count DESC NULLS LAST, posted_at DESC NULLS LAST;
Aquí está el http://sqlfiddle.com/#!15/588e5/1/0 , en el violín de SQL, he definido el esquema, la consulta exacta y el resultado esperado.
Pero el rendimiento de la consulta es lento una vez que la tabla de mensajes se hace grande. Intenté agregar múltiples índices de clasificación, pero no parece usar el índice. Aquí está la explicación: http://explain.depesz.com/s/Sv2
¿Cómo puedo crear un índice correcto?
feed_id
y posted_at
y no mencionó metadata
en absoluto, ¿cuál parece ser un tipo JSON? Repare su pregunta para que sea coherente. Selecciona> 500k filas en el CTE ... ¿Cuántas filas hay en la tabla? ¿Qué porcentaje de filas normalmente selecciona en el CTE? ¿Qué porcentaje de filas tiene parent_id IS NULL
? Considere la información en la etiqueta [postgresql-performance] para preguntas de rendimiento.
parent_id
? (min / avg / max)
metadata
. Actualmente, la tabla de mensajes tiene 10 millones de datos, pero aumenta rápidamente. Creo que se separa en tablas de partición para cada feed_id. Como solo estoy buscando por ID de feed. El porcentaje de parent_id nulo vs no nulo es aproximadamente 60% / 40%. una búsqueda típica es alrededor del 1-2% de la tabla. (alrededor de 100K mensajes) El rendimiento para 100K es de alrededor de 1s, pero una vez que llega a 500K + usa el índice de mapa de bits y normalmente toma 10s.
ORDER BY
en la subconsulta es totalmente inútil. Además, el plan vinculado no puede ser el resultado de la consulta publicadametadata
; por ejemplo, no se menciona nada .