2

に似た値を持つ文字列列が与えられた場合、指定された数値を含むすべてのレコードを/123/12/34/56/5/照会する最適な方法は何ですか(たとえば)?12

私の頭の上からの解決策は次のとおりです。

SELECT id FROM things WHERE things.path LIKE '%/12/%'

しかし、私の知る限り、このクエリは、先頭が原因で列にインデックスを使用できません%

もっと良いものがあるはずです。それは何ですか?

PostgreSQL を使用していますが、他の DB でも機能するソリューションを好むでしょう。

4

2 に答える 2

4

その列を整数の配列に変換してよければ、次のようになります。

'/123/12/34/56/5/' becomes ARRAY[123,12,34,56,5]

これpath_arrは type の列なので、INTEGER[]その列に GIN インデックスを作成できます。

CREATE INDEX ON things USING gin(path_arr);

12 を含むすべてのアイテムのクエリは次のようになります。

SELECT * FROM things WHERE ARRAY[12] <@ path_arr;

インデックスを使用します。私のテスト (100 万行) では、次のような計画が得られます。

EXPLAIN SELECT * FROM things WHERE ARRAY[12]  <@ path_arr;
                                      QUERY PLAN
----------------------------------------------------------------------------------------
 Bitmap Heap Scan on things  (cost=5915.75..9216.99 rows=1000 width=92)
   Recheck Cond: (path_arr <@ '{12}'::integer[])
   ->  Bitmap Index Scan on things_path_arr_idx  (cost=0.00..5915.50 rows=1000 width=0)
         Index Cond: ('{12}'::integer[] <@ path_arr)
(4 rows)
于 2012-04-16T04:59:42.047 に答える
3

PostgreSQL 9.1 では、このpg_trgmモジュールを利用して GIN インデックスを構築できました。

CREATE EXTENSION pg_trgm; -- once per database

CREATE INDEX things_path_trgm_gin_idx ON things USING gin (path gin_trgm_ops);

左アンカーLIKEされていない場合でも、式でこのインデックスを使用できます。

ここで depesz による詳細なデモを参照してください。

ただし、できれば正規化してください。

于 2012-04-16T03:57:39.397 に答える