sql >> Database teknologi >  >> RDS >> PostgreSQL

PostgreSQL ved hjælp af pg_trgm langsommere end fuld scanning

tldr:trigrammer er muligvis ikke gode til at søge efter mønstre, der består af et enkelt tegn, der gentages N gange (såsom 666666 ), fordi der kun eksisterer 1 ikke-terminalt trigram, og det kunne have en høj forekomst i søgeområdet.

Når gin-indekset bruges, er bitmap af rækker for stor til at passe i hukommelsen, så i stedet gemmer den reference til sider, og databasen skal udføre en yderligere gentjek scanning over disse sider. Hvis antallet af gentjekkede sider er lille, er indeksbrugen stadig fordelagtig, men med et højt antal gentjekkede sider klarer indekset dårligt. Dette er fremhævet af de følgende linjer i dit forklaringsoutput

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

Problemet er specifikt for din søgestreng, dvs. 666666 , med hensyn til testdata.

hvis du kører select pg_trgm('666666') , finder du:

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

De første 3 trigrammer vil ikke engang blive genereret i en lignende kontekst (korrektion foreslået af brugeren jjanes ) . Søgning på indekset giver alle sider, der indeholder 666 . Du kan validere dette ved at køre forklaringsanalyseforespørgslen med ... ilike '%666%' , og opnå de samme Heap Blocks output som ovenfor.

hvis du søger med mønsteret 123456 , vil du se, at den yder meget bedre, fordi den genererer et større sæt trigrammer at søge mod:

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

På min maskine får jeg følgende:

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

Her er forklaringsoutputtet:

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. Vil du returnere databaseposter ved hjælp af LinqToSql?

  2. Indstilling af skemanavnet i postgres ved hjælp af R

  3. Hvorfor bruge join i MySQL-forespørgsler i stedet for hvor?

  4. SQLite introducerer UNIXEPOCH()-funktionen