5万行のテーブルがあります。これは実際にはPostGISテーブルです。
クエリには4つの部分があります(1つは必須)(3つはオプション)
返される行は約100-4,000になると思います
テーブルに複合インデックスを作成する場合、どの列を最初に使用する必要がありますか。きめ細かいのはおそらく場所です(データは世界中に広がっています)。現在、Gistインデックスとして持っています。
他のインデックスはBTREEです。
私の直感は、きめ細かい、そして最後のコースを使用すると言います。例えば。約12のファイルタイプしかないため、インデックスのバケットは非常に大きくなります。
PostgreSQLとPostGISの達人(システムの内部を知っている人)は何と言っていますか?
更新:
この質問をもっとはっきりさせましょう。
これらの仮定のいずれかが間違っているかどうか教えてください。 (私は複合インデックスのアイデアにかなり新しいです)
繰り返しになりますが、私は誰かに私のソリューションを設計するように依頼しているのではなく、他の人の作業についてぶつかっていません。しかし、PostGreSQLドキュメントが実装について教えてくれないことが必要です
[まだ表示するEXPLAIN結果がないのは、24Mの行テーブルからこの25Kの行テーブルを作成する必要があるためです。思ったより時間がかかります。私はものを1,000個のアイテムグループにクラスター化し、ユーザーに25K行テーブルに対してクエリを実行させています。しかし、次の質問では、そのクエリの結果を使用してMASTER 25M行テーブルに移動し、物事を引き出します。そのため、複合インデックスのパフォーマンスが実際に低下します。
以下のサンプルクエリ:
SELECT
public.product_list_meta_mv.cntry_name AS country,
public.product_list_meta_mv.product_producer AS producer,
public.product_list_meta_mv.product_name AS prod_name,
public.product_list_meta_mv.product_type AS ptype,
public.product_list_meta_mv.product_size AS size,
ST_AsGeoJSON(public.product_list_meta_mv.the_geom, 10, 2) AS outline
FROM
public.product_list_meta_mv
WHERE
public.product_list_meta_mv.cntry_name = 'Poland'
AND
ST_Intersects(public.product_list_meta_mv.the_geom,
st_geogfromtext('SRID=4326;POLYGON((21.23107910156250 51.41601562500000,
18.64379882812500 51.41601562500000,
18.64379882812500 48.69415283203130,
21.23107910156250 48.69415283203130,
21.23107910156250 51.41601562500000))'))
AND (date >= '1/2/1900 5:00:00 AM'
AND date <= '2/26/2014 10:26:44 PM')
AND (public.product_list_meta_mv.product_type in
('CIB10','DTED0','DTED1','DTED2','CIB01','CIB05')) ;
EXPLAIN ANALYZEの結果(複合インデックスを入れていないため、表示されている速度から、必要かどうかわかりません)。
"Bitmap Heap Scan on catalog_full cat (cost=4.33..37.49 rows=1 width=7428) (actual time=1.147..38.051 rows=35 loops=1)"
" Recheck Cond: ('0103000020E61000000100000005000000000000005838354000000000AEB0494000000000A0A7324000000000AEB0494000000000A0A73240000000006C5D48400000000058383540000000006C5D4840000000005838354000000000AEB04940'::geography && outline)"
" Filter: (((type)::text = ANY ('{CADRG,CIB10,DTED1,DTED2}'::text[])) AND (_st_distance('0103000020E61000000100000005000000000000005838354000000000AEB0494000000000A0A7324000000000AEB0494000000000A0A73240000000006C5D48400000000058383540000000006C5D4840000000005838354000000000AEB04940'::geography, outline, 0::double precision, false) < 1e-005::double precision))"
" Rows Removed by Filter: 61"
" -> Bitmap Index Scan on catalog_full_outline_idx (cost=0.00..4.33 rows=8 width=0) (actual time=0.401..0.401 rows=96 loops=1)"
" Index Cond: ('0103000020E61000000100000005000000000000005838354000000000AEB0494000000000A0A7324000000000AEB0494000000000A0A73240000000006C5D48400000000058383540000000006C5D4840000000005838354000000000AEB04940'::geography && outline)"
"Total runtime: 38.109 ms"
EXPLAIN ANALYZE SELECT pid,product_name,type,country,date,size,cocom,description,egpl_date,ST_AsGeoJSON(outline, 10, 2) AS outline
FROM portal.catalog_full AS cat
WHERE ST_Intersects(st_geogfromtext('SRID=4326;POLYGON((21.2200927734375 51.38031005859375, 18.65478515625 51.38031005859375, 18.65478515625 48.7298583984375, 21.2200927734375 48.7298583984375, 21.2200927734375 51.38031005859375))'), cat.outline)
AND (cat.type in ('CADRG','CIB10','DTED1','DTED2'))
私の仕事の一環として、かなり大きなPostgreSQLデータベース(ディスク上に約120GB、数百万行のテーブル)を維持し、クエリを高速化する方法に関するいくつかのトリックを収集しました。最初に、仮定についていくつかコメントします。
4ウェイインデックスを作成しないことをお勧めします。作成してサイズを確認してください。非常に大きくなる可能性があります。私の経験では、4つの1キーインデックスは、単一の4ウェイインデックスとほぼ同じ速さでした。特定のクエリでうまく機能するトリックは、部分インデックスです。つまり、次のようなものです。
CREATE INDEX ON table_x(key1、key2、key3)WHERE some_x_column = 'XXXX';
追加または削除するインデックスの検索に役立つクエリを使用して、.psqlrcファイルにエイリアスを作成しました。 GitHubで自由に見てください: 。psql
:seq_scansと:bigtablesを頻繁に使用し、\ d table_nameを使用してテーブルの詳細を取得します。いくつかの変更を行った後、統計をリセットすることを忘れないでください、pg_stat_reset();を選択します。
(もしあれば)最も役立つ可能性が高いのは、Gistインデックスの2番目の列としてproduct_typeを追加することだと思います。しかし、典型的な/問題のあるクエリのAND条件のそれぞれに(いくつも)一致する行の数がわからなければ、推測することしかできません。
これに近づくと、最初に行うことは、単純化された形式でクエリを実行することです。ここで、WHERE句には1つの条件のみがあり、それぞれがEXPLAIN ANALYZEで順番に実行されます。それぞれの推定行と実際の行の両方を見てください。