sql >> Base de Datos >  >> RDS >> PostgreSQL

Optimización de GROUP BY + COUNT DISTINCT en una columna jsonb no anidada

Asumiendo id no solo UNIQUE - según lo exija su UNIQUE INDEX - pero también NOT NULL . (Eso falta en la definición de su tabla).

SELECT meta_split.key, meta_split.value, count(*)
FROM   voc_cc348779bdc84f8aab483f662a798a6a v
CROSS  JOIN LATERAL jsonb_each(v.meta) AS meta_split
GROUP  BY meta_split.key, meta_split.value;

Equivalente más corto:

SELECT meta_split.key, meta_split.value, count(*)
FROM   voc_cc348779bdc84f8aab483f662a798a6a v, jsonb_each(v.meta) AS meta_split
GROUP  BY 1, 2;

El LEFT [OUTER] JOIN hubo ruido porque la siguiente prueba WHERE meta_split.value IS NOT NULL fuerza una INNER JOIN de todos modos. Usando CROSS JOIN en su lugar.

Además, desde jsonb no permite claves duplicadas en el mismo nivel de todos modos (es decir, el mismo id solo puede aparecer una vez por (key, value) ), DISTINCT es solo un ruido caro. count(v.id) hace lo mismo más barato. Y count(*) es equivalente y más barato, sin embargo, asumiendo id es NOT NULL como se indica en la parte superior.

count(*) tiene una implementación separada y es un poco más rápido que count(<value>) . Es sutilmente diferente de count(v.*) . Cuenta todas las filas, pase lo que pase. Mientras que la otra forma no cuenta NULL valores.

Es decir, siempre que id no puede ser NULL - como se indica en la parte superior. id debería ser realmente la PRIMARY KEY , que se implementa con un índice de árbol B único internamente de todos modos, y todas las columnas:solo id aquí - son NOT NULL implícitamente. O al menos NOT NULL . UN UNIQUE INDEX no califica completamente como reemplazo, todavía permite NULL valores que no se consideran iguales y se permiten varias veces. Ver:

Aparte de eso, los índices no sirven aquí, ya que todas las filas deben leerse de todos modos. Así que esto nunca va a ser muy barato. Pero 62k filas no es un recuento de filas paralizante de ninguna manera, a menos que tenga una gran cantidad de claves en el jsonb columna.

Las opciones restantes para acelerarlo:

  1. Normaliza tu diseño. Deshacer el anidamiento de documentos JSON no es gratis.

  2. Mantener una visión materializada. La viabilidad y los costos dependen en gran medida de sus patrones de escritura.

Ahí es donde los índices pueden volver a jugar un papel...