tldr:トリグラムは、N回繰り返される単一の文字で構成されるパターンの検索に適していない場合があります(666666
など)。 )非終端記号が1つしか存在せず、可能性がある サーチスペースでの発生率が高い。
gin-indexを使用すると、行のビットマップが大きすぎてメモリに収まらないため、代わりにページへの参照が格納され、データベースはこれらのページに対してさらに再チェックスキャンを実行する必要があります。再チェックされたページの数が少ない場合でも、インデックスの使用は有益ですが、再チェックされたページの数が多いと、インデックスのパフォーマンスが低下します。これは、Explain出力の次の行で強調表示されています
Recheck Cond: (x ~~* '%666666%'::text)
Rows Removed by Index Recheck: 36257910
Heap Blocks: exact=39064 lossy=230594
この問題は検索文字列に固有です。つまり、666666
、テストデータに関して。
select pg_trgm('666666')
を実行する場合 、次のようになります:
show_trgm
-------------------------
{" 6"," 66","66 ",666}
(1 row)
最初の3つのトリグラムはilikeコンテキストでは生成されません(ユーザーjjanes<によって修正が提案されました/ a> ) 。インデックスを検索すると、666
を含むすべてのページが表示されます 。これを検証するには、... ilike '%666%'
を使用してexplainanalyzeクエリを実行します。 、同じHeap Blocks
を取得します 上記のように出力します。
パターン123456
で検索する場合 、検索対象のトリグラムのセットが大きくなるため、パフォーマンスが大幅に向上します。
show_trgm
-------------------------------------
{" 1"," 12",123,234,345,456,"56 "}
(1 row)
私のマシンでは、次のようになります。
|------------------------------------|
| 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'
説明の出力は次のとおりです。
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)