2009-10-08 13 views
15

StackOverflowの9月のデータダンプをサンプルデータとして使用して、PostgreSQLのテキスト検索機能をテストしています。 :-)なぜPostgreSQLのテキスト検索GiSTインデックスはGINインデックスよりもはるかに遅いのですか?

120万行を検索し、一致LIKE述語やPOSIX正規表現を使用しての単純なアプローチは、キーワードを探して全表スキャンを実行するために(私のMacBook上)について90-105秒かかります。

SELECT * FROM Posts WHERE body LIKE '%postgresql%'; 
SELECT * FROM Posts WHERE body ~ 'postgresql'; 

インデックスのない、アドホックテキスト検索クエリを約8分を取る:GINインデックスを作成する

SELECT * FROM Posts WHERE to_tsvector(body) @@ to_tsquery('postgresql'); 

40分取ります

ALTER TABLE Posts ADD COLUMN PostText TSVECTOR; 
UPDATE Posts SET PostText = to_tsvector(body); 
CREATE INDEX PostText_GIN ON Posts USING GIN(PostText); 

を(I表現インデックスとして定義することで、これを1つのステップで行うこともできます。

私はGiSTインデックスを作成するときに

SELECT * FROM Posts WHERE PostText @@ 'postgresql'; 

は、しかし、結果はかなり異なっている:これは約40ミリ秒を取る -

その後、GINインデックスにより補助クエリがはるかに高速に実行されます。

CREATE INDEX PostText_GIN ON Posts USING GIST(PostText); 

その後、@@テキスト検索演算子を使用してクエリが90-100秒とります。これは、インデックスを作成するために、以下2分かかります。したがって、GiSTインデックスは、索引付けされていないTSクエリを8分から1.5分に改善します。しかし、それはLIKEで完全なテーブルスキャンを行うよりも改善されていません。ウェブプログラミング環境では役に立たない。

私はGiSTインデックスを使用する上で重要な何かを見逃していますか?索引をメモリなどにプリキャッシュする必要がありますか?私はMacPortsからの単純なPostgreSQLインストールを使用していますが、調整はしていません。

GiSTインデックスを使用する推奨される方法は何ですか?あるいは、PostgreSQLでTSをやっている人は誰もGiSTインデックスをスキップし、GINインデックスのみを使用しますか?

PS:私はSphinx SearchやLuceneのような選択肢について知っています。私はPostgreSQL自体が提供する機能について学びたいだけです。

答えて

5

は、プレフィックスクエリの適切なインデックスを作成します

CREATE INDEX PostText_GIST ON Posts USING GIST(PostText varchar_pattern_ops); 

を試してみてください。 PostgreSQLのドキュメントOperator Classes and Operator Familiesを参照してください。 @@演算子は、項ベクトル上でのみ意味があります。 GiSTインデックス(varchar_pattern_opsを使用)は、LIKEで優れた結果を得られます。

+0

感謝されている必要があり、私は」あなたの提案を試してみよう... –

+1

そのインデックスを生成するのにかなり時間がかかっているに違いありません。 :) –

+5

'varchar_pattern_ops'が' varchar'型で、 'PostText'が' tsvector'型で、 'bstree'と' hash'インデックスのみで定義され、 'gist'では定義されていないので、これはうまく動作しません。 –

6

興味があれば、ドキュメントには、GiSTインデックスとGINインデックスのパフォーマンスの相違点の素晴らしい概要があります。GiST and GIN Index Types

2

ところで:これはまだあなたの満足に答えられていない場合、あなたは

SELECT * FROM Posts WHERE PostText @@ 'postgresql';

をした部分は、あなたの答えのために

SELECT * FROM Posts WHERE PostText @@ to_tsquery('postgresql');

+0

チップをありがとう、私はPostgreSQLをテストする次回試してみます。私はMySQLをかなり独占的に数年間使用してきました。 –

関連する問題