sql >> Databáze >  >> RDS >> PostgreSQL

PostgreSQL pomocí pg_trgm je pomalejší než úplné skenování

tldr:trigramy nemusí být dobré při hledání vzorů skládajících se z jednoho znaku, který se Nkrát opakuje (například 666666 ), protože existuje pouze 1 neterminální trigram a to mohlo mají vysoký výskyt ve vyhledávacím prostoru.

Při použití gin-indexu je bitmapa řádků příliš velká, aby se vešla do paměti, takže místo toho ukládá odkazy na stránky a databáze musí tyto stránky znovu zkontrolovat. Pokud je počet znovu zkontrolovaných stránek malý, je použití indexu stále výhodné, ale při vysokém počtu znovu zkontrolovaných stránek index funguje špatně. To je zvýrazněno následujícími řádky ve vašem výstupu vysvětlení

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

Problém se týká vašeho vyhledávacího řetězce, tj. 666666 , s ohledem na testovací data.

pokud spustíte select pg_trgm('666666') , najdete:

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

První 3 trigramy nebudou ani generovány v podobném kontextu (oprava navržená uživatelem jjanes ) . Vyhledávání v indexu poskytne všechny stránky obsahující 666 . Můžete to ověřit spuštěním dotazu Explain analysis s ... ilike '%666%' a získání stejných Heap Blocks výstup jako výše.

pokud hledáte pomocí vzoru 123456 , uvidíte, že funguje mnohem lépe, protože generuje větší sadu trigramů pro vyhledávání:

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

Na mém počítači se mi zobrazí následující:

|------------------------------------|
| 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'

Zde je výstup vysvětlení:

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)


  1. Deaktivace agenta v EM13c

  2. Existuje nějaká funkce v oracle podobná group_concat v mysql?

  3. Innodb:Při dotazu na více než 1 sloupec nelze najít FULLTEXTOVÝ index odpovídající seznamu sloupců

  4. PostgreSQL přetypování součtu jako bigint