PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

PostgreSQL utilisant pg_trgm plus lent que l'analyse complète

tldr :les trigrammes peuvent ne pas être efficaces pour rechercher des motifs constitués d'un seul caractère répété N fois (comme 666666 ) car il n'existe qu'un seul trigramme non terminal et cela pourrait ont une occurrence élevée dans l'espace de recherche.

Lorsque le gin-index est utilisé, le bitmap des lignes est trop volumineux pour tenir en mémoire, il stocke donc à la place la référence aux pages, et la base de données doit effectuer une nouvelle analyse de vérification sur ces pages. Si le nombre de pages revérifiées est faible, l'utilisation de l'index est toujours bénéfique, mais avec un nombre élevé de pages revérifiées, l'index fonctionne mal. Ceci est mis en évidence par les lignes suivantes dans votre sortie d'explication

   Recheck Cond: (x ~~* '%666666%'::text)
   Rows Removed by Index Recheck: 36257910
   Heap Blocks: exact=39064 lossy=230594

Le problème est particulier à votre chaîne de recherche, c'est-à-dire 666666 , par rapport aux données de test.

si vous exécutez select pg_trgm('666666') , vous trouverez :

        show_trgm        
-------------------------
 {"  6"," 66","66 ",666}
(1 row)

Les 3 premiers trigrammes ne seront même pas générés dans un contexte similaire (correction suggérée par l'utilisateur jjanes ) . La recherche sur l'index donne toutes les pages contenant 666 . Vous pouvez valider cela en exécutant la requête d'analyse d'explication avec ... ilike '%666%' , et obtenir les mêmes Heap Blocks sortie comme ci-dessus.

si vous recherchez avec le motif 123456 , vous verrez qu'il fonctionne beaucoup mieux, car il génère un plus grand ensemble de trigrammes à rechercher :

              show_trgm              
-------------------------------------
 {"  1"," 12",123,234,345,456,"56 "}
(1 row)

Sur ma machine, j'obtiens ceci :

|------------------------------------|
| pattern | pages rechecked          |
|         | exact | lossy  | total   |
|------------------------------------|
| 123456  |   600 |        |    600  |
| 666666  | 39454 | 230592 | 270046* |
|    666  | 39454 | 230592 | 270046* |
|------------------------------------|
*this is rougly 85% of the total # of pages used for the table 't'

Voici la sortie d'explication :

postgres=> explain analyze select * from t where x ~ '123456';
                                                        QUERY PLAN                                                        
--------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on t  (cost=90.75..18143.92 rows=5000 width=22) (actual time=110.962..113.509 rows=518 loops=1)
   Recheck Cond: (x ~ '123456'::text)
   Rows Removed by Index Recheck: 83
   Heap Blocks: exact=600
   ->  Bitmap Index Scan on t_x_idx  (cost=0.00..89.50 rows=5000 width=0) (actual time=110.868..110.868 rows=601 loops=1)
         Index Cond: (x ~ '123456'::text)
 Planning time: 0.703 ms
 Execution time: 113.564 ms
(8 rows)

postgres=> explain analyze select * from t where x ~ '666666';
                                                         QUERY PLAN                                                          
-----------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on t  (cost=54.75..18107.92 rows=5000 width=22) (actual time=137.143..18111.609 rows=462 loops=1)
   Recheck Cond: (x ~ '666666'::text)
   Rows Removed by Index Recheck: 36258389
   Heap Blocks: exact=39454 lossy=230592
   ->  Bitmap Index Scan on t_x_idx  (cost=0.00..53.50 rows=5000 width=0) (actual time=105.962..105.962 rows=593708 loops=1)
         Index Cond: (x ~ '666666'::text)
 Planning time: 0.420 ms
 Execution time: 18111.739 ms
(8 rows)

postgres=> explain analyze select * from t where x ~ '666';
                                                        QUERY PLAN                                                         
---------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on t  (cost=54.75..18107.92 rows=5000 width=22) (actual time=102.813..17285.086 rows=593708 loops=1)
   Recheck Cond: (x ~ '666'::text)
   Rows Removed by Index Recheck: 35665143
   Heap Blocks: exact=39454 lossy=230592
   ->  Bitmap Index Scan on t_x_idx  (cost=0.00..53.50 rows=5000 width=0) (actual time=96.100..96.100 rows=593708 loops=1)
         Index Cond: (x ~ '666'::text)
 Planning time: 0.500 ms
 Execution time: 17300.440 ms
(8 rows)