0

PostgreSQL テーブルに巨大なパーティション テーブルが格納されています。各子テーブルには、インデックスとその ID に対するチェック制約があります。たとえば、(わかりやすくするために無関係な詳細は削除されています)。

Master table: points
    Column     |            Type             |       Modifiers        
---------------+-----------------------------+------------------------
 id            | bigint                      |
 creation_time | timestamp without time zone | 
 the_geom      | geometry                    | 


Sub-table points_01
    Column     |            Type             |        Modifiers        
---------------+-----------------------------+-------------------------
     id            | bigint                      | 
 creation_time | timestamp without time zone | 
 the_geom      | geometry                    | 

Indexes:
    "points_01_pkey" PRIMARY KEY, btree (id)
    "points_01_creation_time_idx" btree (creation_time)
    "points_01_the_geom_idx" gist (the_geom) CLUSTER
Check constraints:
    "enforce_srid_the_geom" CHECK (srid(the_geom) = 4326)
    "id_gps_points_2010_08_22__14_47_04_check" 
               CHECK (id >= 1000000::bigint AND id <= 2000000::bigint)

今、

SELECT max(id) FROM points_01

インスタントですが、次のとおりです。

SELECT max(id) FROM points

これはマスター テーブルでpoints_01 .. points_60あり、チェック制約を使用するとほとんど時間がかからないはずですが、クエリ プランナーがチェック制約を使用しないため、1 時間以上かかります。

PostgreSQL wiki (このページの最後のセクション) によると、これは既知の問題であり、次のバージョンで修正される予定です。

max()クエリ プランナーがチェック制約とクエリのサブテーブルのインデックスを利用するようにする良いハックはありますmin()か?

ありがとう、

アダム

4

3 に答える 3

2

それが機能するかどうかはわかりませんが、これを試すことができます:

そのセッションでは、インデックス付きのものを除くすべてのアクセス戦略を無効にすることができます。

db=> set enable_seqscan = off;
db=> set enable_tidscan = off;
db=> -- your query goes here

この方法でのみbitmapscanindexscan有効になります。PostgreSQLは、インデックスを使用してテーブル上のデータにアクセスする以外に選択肢はありません。

クエリを実行した後、次の手順を実行して、再度有効seqscantidscanすることを忘れないでください。

db=> set enable_seqscan = on;
db=> set enable_tidscan = on;

それ以外の場合、これらのアクセス戦略は、その時点以降のセッションでは無効になります。

于 2010-10-06T17:03:00.557 に答える
1

簡単な答え: いいえ。現時点では、いくつかの集計関数が最初に子パーティションの制約をチェックできることを Postgres プランナーに理解させる方法はありません。最小値と最大値の特定のケースを証明するのはかなり簡単ですが、一般に集計の場合は難しいケースです。

実行する必要がある場合は、いつでも複数のパーティションの UNION として書き込むことができます...

于 2010-10-06T21:56:57.777 に答える
0

私はpostgresについてあまり知りませんが、このクエリを試すことができます(postgresクエリの経験が不足しているため、私のクエリ構文は正しくない可能性があります):

SELECT id FROM points a WHERE id > ALL (SELECT id FROM x WHERE x.id != a.id)

これがうまくいくかどうか、私は興味があります。

于 2010-10-07T16:56:37.013 に答える