Le query full-text su questo database (memorizzazione dei ticket RT ( Request Tracker ) sembrano richiedere molto tempo per essere eseguite. La tabella degli allegati (contenente i dati full text) è di circa 15 GB.
Lo schema del database è il seguente, circa 2 milioni di righe:
rt4 = # \ d + allegati Tabella "public.attachments" Colonna | Digita | Modificatori | Conservazione | Descrizione ----------------- + ----------------------------- + - -------------------------------------------------- ------ + ---------- + ------------- id | intero | nextval default non nullo ('attachments_id_seq' :: regclass) | pianura | transazione | intero | non nullo | pianura | genitore | intero | non null default 0 | pianura | messageid | carattere variabile (160) | | esteso | soggetto | carattere variabile (255) | | esteso | nome file | carattere variabile (255) | | esteso | contenttype | carattere variabile (80) | | esteso | codifica dei contenuti | carattere variabile (80) | | esteso | contenuto | testo | | esteso | intestazioni | testo | | esteso | creatore | intero | non null default 0 | pianura | creato | timestamp senza fuso orario | | pianura | contentindex | tsvector | | esteso | indici: TASTO PRIMARIO "attachments_pkey", btree (id) "attachments1" btree (genitore) "attachments2" btree (transactionid) "attachments3" btree (padre, transazione) "contentindex_idx" gin (contentindex) Ha OID: no
Posso interrogare il database da solo molto rapidamente (<1s) con una query come:
select objectid
from attachments
join transactions on attachments.transactionid = transactions.id
where contentindex @@ to_tsquery('frobnicate');
Tuttavia, quando RT esegue una query che dovrebbe eseguire una ricerca dell'indice full-text sulla stessa tabella, il completamento richiede in genere centinaia di secondi. L'output dell'analisi della query è il seguente:
domanda
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
produzione
PIANO DI QUERY -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------- Aggregato (costo = 51210.60..51210.61 righe = 1 larghezza = 4) (tempo effettivo = 477778.806..477778.806 righe = 1 loop = 1) -> Loop nidificato (costo = 0,00..51210,57 righe = 15 larghezza = 4) (tempo effettivo = 17943,986..477775.174 righe = 4197 loop = 1) -> Nested Loop (costo = 0.00..40643.08 righe = 6507 larghezza = 8) (tempo effettivo = 8.526..20610.380 righe = 1714818 loop = 1) -> Scansione Seq su ticket principale (costo = 0,00..9818,37 righe = 598 larghezza = 8) (tempo effettivo = 0,008..256,042 righe = 96990 loop = 1) Filtro: (((stato) :: testo 'cancellato' :: testo) AND (id = efficace) AND ((tipo) :: testo = 'ticket' :: testo)) -> Scansione indice utilizzando le transazioni1 sulle transazioni_1 (costo = 0,00..51,36 righe = 15 larghezza = 8) (tempo effettivo = 0,102..0,202 righe = 18 cicli = 96990) Index Cond: ((((objecttype) :: text = 'RT :: Ticket' :: text) AND (objectid = main.id)) -> Scansione indice utilizzando allegati2 su allegati attachments_2 (costo = 0,00..1,61 righe = 1 larghezza = 4) (tempo effettivo = 0,266..0,266 righe = 0 loop = 1714818) Indice cond: (transactionid = transazioni_1.id) Filtro: (contentindex @@ plainto_tsquery ('frobnicate' :: text)) Durata totale: 477778.883 ms
Per quanto posso dire, il problema sembra essere che non sta usando l'indice creato sul contentindex
campo ( contentindex_idx
), piuttosto sta facendo un filtro su un gran numero di righe corrispondenti nella tabella degli allegati. Anche i conteggi delle righe nell'output di spiegazione sembrano essere imprecisi, anche dopo un recente ANALYZE
: righe stimate = 6507 righe effettive = 1714818.
Non sono davvero sicuro di dove andare dopo con questo.