Les requêtes en texte intégral sur cette base de données (stockage de tickets RT ( Request Tracker )) semblent prendre beaucoup de temps à s'exécuter. Le tableau des pièces jointes (contenant les données de texte intégral) est d'environ 15 Go.
Le schéma de la base de données est le suivant, c'est environ 2 millions de lignes:
rt4 = # \ d + pièces jointes Tableau "public.attachments" Colonne | Type | Modificateurs | Stockage | La description ----------------- + ----------------------------- + - -------------------------------------------------- ------ + ---------- + ------------- id | entier | non nul par défaut nextval ('attachments_id_seq' :: regclass) | ordinaire | transactionid | entier | non nul | ordinaire | parent | entier | non nul par défaut 0 | ordinaire | messageid | caractère variable (160) | | étendu | sujet | caractère variable (255) | | étendu | nom de fichier | caractère variable (255) | | étendu | type de contenu | caractère variable (80) | | étendu | codage de contenu | caractère variable (80) | | étendu | contenu | texte | | étendu | en-têtes | texte | | étendu | créateur | entier | non nul par défaut 0 | ordinaire | créé | horodatage sans fuseau horaire | | ordinaire | contentindex | tsvector | | étendu | Index: "attachments_pkey" CLÉ PRIMAIRE, btree (id) "attachments1" btree (parent) "attachments2" btree (transactionid) "attachments3" btree (parent, transactionid) Gin "contentindex_idx" (contentindex) Possède des OID: non
Je peux interroger la base de données d'elle-même très rapidement (<1s) avec une requête telle que:
select objectid
from attachments
join transactions on attachments.transactionid = transactions.id
where contentindex @@ to_tsquery('frobnicate');
Cependant, lorsque RT exécute une requête qui est censée effectuer une recherche d'index de texte intégral sur la même table, cela prend généralement des centaines de secondes. La sortie d'analyse de la requête est la suivante:
Requete
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
production
PLAN DE DEMANDE -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------- Agrégat (coût = 51210.60..51210.61 lignes = 1 largeur = 4) (temps réel = 477778.806..477778.806 lignes = 1 boucles = 1) -> Boucle imbriquée (coût = 0,00..51210,57 lignes = 15 largeur = 4) (temps réel = 17943,986..477775,174 lignes = 4197 boucles = 1) -> Boucle imbriquée (coût = 0,00..40643,08 lignes = 6507 largeur = 8) (temps réel = 8,526..20610,380 lignes = 1714818 boucles = 1) -> Seq Scan sur les tickets principaux (coût = 0,00..9818,37 lignes = 598 largeur = 8) (temps réel = 0,008..256,042 lignes = 96990 boucles = 1) Filtre: ((((status) :: text 'supprimé' :: text) AND (id = effectiveid) AND ((type) :: text = 'ticket' :: text)) -> Index Scan en utilisant transactions1 sur transactions transactions_1 (coût = 0,00..51,36 lignes = 15 largeur = 8) (temps réel = 0,102..0,202 lignes = 18 boucles = 96990) Index Cond: (((objecttype) :: text = 'RT :: Ticket' :: text) AND (objectid = main.id)) -> Index Scan en utilisant les pièces jointes2 sur les pièces jointes attachments_2 (coût = 0,00..1,61 lignes = 1 largeur = 4) (temps réel = 0,266..0,266 lignes = 0 boucles = 1714818) Index Cond: (transactionid = transactions_1.id) Filtre: (contentindex @@ plainto_tsquery ('frobnicate' :: text)) Durée d'exécution totale: 477778,883 ms
Pour autant que je sache, le problème semble être qu'il n'utilise pas l'index créé sur le contentindex
champ ( contentindex_idx
), mais plutôt qu'il filtre un grand nombre de lignes correspondantes dans la table des pièces jointes. Le nombre de lignes dans la sortie d'explication semble également extrêmement inexact, même après une récente ANALYZE
: lignes estimées = 6507 lignes réelles = 1714818.
Je ne sais pas vraiment où aller ensuite avec ça.