Las consultas de texto completo en esta base de datos (almacenamiento de tickets RT ( Request Tracker )) parecen tardar mucho tiempo en ejecutarse. La tabla de archivos adjuntos (que contiene los datos de texto completo) es de aproximadamente 15 GB.
El esquema de la base de datos es el siguiente, es de aproximadamente 2 millones de filas:
rt4 = # \ d + archivos adjuntos Tabla "archivos adjuntos públicos" Columna | Tipo | Modificadores | Almacenamiento | Descripción ----------------- + ----------------------------- + - -------------------------------------------------- ------ + ---------- + ------------- id | entero | nextval no nulo predeterminado ('attachments_id_seq' :: regclass) | llano | transaccion | entero | no nulo | llano | padre | entero | no nulo predeterminado 0 | llano | messageid | carácter variable (160) | El | extendido | sujeto | carácter variable (255) | El | extendido | nombre de archivo | carácter variable (255) | El | extendido | contenttype | carácter variable (80) | El | extendido | contentencoding | carácter variable (80) | El | extendido | contenido | texto | El | extendido | encabezados | texto | El | extendido | creador | entero | no nulo predeterminado 0 | llano | creado | marca de tiempo sin zona horaria | El | llano | contentindex | tsvector | El | extendido | Índices: "attachments_pkey" CLAVE PRIMARIA, btree (id) "adjuntos1" btree (padre) btree "adjuntos2" (transacciónid) btree "adjuntos3" (padre, transacciónid) Ginebra "contentindex_idx" (contentindex) Tiene OID: no
Puedo consultar la base de datos por sí sola muy rápidamente (<1s) con una consulta como:
select objectid
from attachments
join transactions on attachments.transactionid = transactions.id
where contentindex @@ to_tsquery('frobnicate');
Sin embargo, cuando RT ejecuta una consulta que se supone que realiza una búsqueda de índice de texto completo en la misma tabla, generalmente tarda cientos de segundos en completarse. La salida de análisis de consulta es la siguiente:
Consulta
SELECT COUNT(DISTINCT main.id)
FROM Tickets main
JOIN Transactions Transactions_1 ON ( Transactions_1.ObjectType = 'RT::Ticket' )
AND ( Transactions_1.ObjectId = main.id )
JOIN Attachments Attachments_2 ON ( Attachments_2.TransactionId = Transactions_1.id )
WHERE (main.Status != 'deleted')
AND ( ( ( Attachments_2.ContentIndex @@ plainto_tsquery('frobnicate') ) ) )
AND (main.Type = 'ticket')
AND (main.EffectiveId = main.id);
EXPLAIN ANALYZE
salida
PLAN DE CONSULTA -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------- Agregado (costo = 51210.60..51210.61 filas = 1 ancho = 4) (tiempo real = 477778.806..477778.806 filas = 1 bucles = 1) -> Bucle anidado (costo = 0.00..51210.57 filas = 15 ancho = 4) (tiempo real = 17943.986..477775.174 filas = 4197 bucles = 1) -> Bucle anidado (costo = 0.00..40643.08 filas = 6507 ancho = 8) (tiempo real = 8.526..20610.380 filas = 1714818 bucles = 1) -> Seq Scan en tickets principales (costo = 0.00..9818.37 filas = 598 ancho = 8) (tiempo real = 0.008..256.042 filas = 96990 bucles = 1) Filtro: (((estado) :: texto 'eliminado' :: texto) Y (id = efectivo) Y ((tipo) :: texto = 'ticket' :: texto)) -> Escaneo de índice usando transacciones1 en transacciones transacciones_1 (costo = 0.00..51.36 filas = 15 ancho = 8) (tiempo real = 0.102..0.202 filas = 18 bucles = 96990) Índice Cond: (((objecttype) :: text = 'RT :: Ticket' :: text) AND (objectid = main.id)) -> Escaneo de índice usando archivos adjuntos2 en archivos adjuntos archivos adjuntos_2 (costo = 0.00..1.61 filas = 1 ancho = 4) (tiempo real = 0.266..0.266 filas = 0 bucles = 1714818) Índice Cond: (transaccion = transacciones_1.id) Filtro: (contentindex @@ plainto_tsquery ('frobnicate' :: text)) Tiempo de ejecución total: 477778.883 ms
Por lo que puedo decir, el problema parece ser que no está usando el índice creado en el contentindex
campo ( contentindex_idx
), sino que está haciendo un filtro en una gran cantidad de filas coincidentes en la tabla de archivos adjuntos. Los recuentos de filas en la salida de explicación también parecen ser muy inexactos, incluso después de un reciente ANALYZE
: filas estimadas = 6507 filas reales = 1714818.
No estoy realmente seguro de a dónde ir después con esto.