私は大きなテーブルをPostgresに持っています。Postgresパーティションのプルーニング
テーブル名はbigtable
あると列は、次のとおりです。
integer |timestamp |xxx |xxx |...|xxx
category_id|capture_time|col1|col2|...|colN
私はcapture_time列のCATEGORY_IDと日付部分のモジュロ10の表をパーティション化しています。
パーティションテーブルは次のようになります。
CREATE TABLE myschema.bigtable_d000h0(
CHECK (category_id%10=0 AND capture_time >= DATE '2012-01-01' AND capture_time < DATE '2012-01-02')
) INHERITS (myschema.bigtable);
CREATE TABLE myschema.bigtable_d000h1(
CHECK (category_id%10=1 AND capture_time >= DATE '2012-01-01' AND capture_time < DATE '2012-01-02')
) INHERITS (myschema.bigtable);
私はWHERE句でCATEGORY_IDとcapture_timeでクエリを実行すると予想されるように、パーティションが剪定されていません。私はwhere句で正確な剰余基準(category_id%10=0
)を追加した場合
explain select * from bigtable where capture_time >= '2012-01-01' and capture_time < '2012-01-02' and category_id=100;
"Result (cost=0.00..9476.87 rows=1933 width=216)"
" -> Append (cost=0.00..9476.87 rows=1933 width=216)"
" -> Seq Scan on bigtable (cost=0.00..0.00 rows=1 width=210)"
" Filter: ((capture_time >= '2012-01-01 00:00:00'::timestamp without time zone) AND (capture_time < '2012-01-02 00:00:00'::timestamp without time zone) AND (category_id = 100))"
" -> Seq Scan on bigtable_d000h0 bigtable (cost=0.00..1921.63 rows=1923 width=216)"
" Filter: ((capture_time >= '2012-01-01 00:00:00'::timestamp without time zone) AND (capture_time < '2012-01-02 00:00:00'::timestamp without time zone) AND (category_id = 100))"
" -> Seq Scan on bigtable_d000h1 bigtable (cost=0.00..776.93 rows=1 width=218)"
" Filter: ((capture_time >= '2012-01-01 00:00:00'::timestamp without time zone) AND (capture_time < '2012-01-02 00:00:00'::timestamp without time zone) AND (category_id = 100))"
" -> Seq Scan on bigtable_d000h2 bigtable (cost=0.00..974.47 rows=1 width=216)"
" Filter: ((capture_time >= '2012-01-01 00:00:00'::timestamp without time zone) AND (capture_time < '2012-01-02 00:00:00'::timestamp without time zone) AND (category_id = 100))"
" -> Seq Scan on bigtable_d000h3 bigtable (cost=0.00..1351.92 rows=1 width=214)"
" Filter: ((capture_time >= '2012-01-01 00:00:00'::timestamp without time zone) AND (capture_time < '2012-01-02 00:00:00'::timestamp without time zone) AND (category_id = 100))"
" -> Seq Scan on bigtable_d000h4 bigtable (cost=0.00..577.04 rows=1 width=217)"
" Filter: ((capture_time >= '2012-01-01 00:00:00'::timestamp without time zone) AND (capture_time < '2012-01-02 00:00:00'::timestamp without time zone) AND (category_id = 100))"
" -> Seq Scan on bigtable_d000h5 bigtable (cost=0.00..360.67 rows=1 width=219)"
" Filter: ((capture_time >= '2012-01-01 00:00:00'::timestamp without time zone) AND (capture_time < '2012-01-02 00:00:00'::timestamp without time zone) AND (category_id = 100))"
" -> Seq Scan on bigtable_d000h6 bigtable (cost=0.00..1778.18 rows=1 width=214)"
" Filter: ((capture_time >= '2012-01-01 00:00:00'::timestamp without time zone) AND (capture_time < '2012-01-02 00:00:00'::timestamp without time zone) AND (category_id = 100))"
" -> Seq Scan on bigtable_d000h7 bigtable (cost=0.00..315.82 rows=1 width=216)"
" Filter: ((capture_time >= '2012-01-01 00:00:00'::timestamp without time zone) AND (capture_time < '2012-01-02 00:00:00'::timestamp without time zone) AND (category_id = 100))"
" -> Seq Scan on bigtable_d000h8 bigtable (cost=0.00..372.06 rows=1 width=219)"
" Filter: ((capture_time >= '2012-01-01 00:00:00'::timestamp without time zone) AND (capture_time < '2012-01-02 00:00:00'::timestamp without time zone) AND (category_id = 100))"
" -> Seq Scan on bigtable_d000h9 bigtable (cost=0.00..1048.16 rows=1 width=215)"
" Filter: ((capture_time >= '2012-01-01 00:00:00'::timestamp without time zone) AND (capture_time < '2012-01-02 00:00:00'::timestamp without time zone) AND (category_id = 100))"
しかし、それはパーティションの剪定作業を行うためにどのような方法が正しくモジュロを追加することなく、あるの
explain select * from bigtable where capture_time >= '2012-01-01' and capture_time < '2012-01-02' and category_id=100 and category_id%10=0;
"Result (cost=0.00..2154.09 rows=11 width=215)"
" -> Append (cost=0.00..2154.09 rows=11 width=215)"
" -> Seq Scan on bigtable (cost=0.00..0.00 rows=1 width=210)"
" Filter: ((capture_time >= '2012-01-01 00:00:00'::timestamp without time zone) AND (capture_time < '2012-01-02 00:00:00'::timestamp without time zone) AND (category_id = 100) AND ((category_id % 10) = 0))"
" -> Seq Scan on bigtable_d000h0 bigtable (cost=0.00..2154.09 rows=10 width=216)"
" Filter: ((capture_time >= '2012-01-01 00:00:00'::timestamp without time zone) AND (capture_time < '2012-01-02 00:00:00'::timestamp without time zone) AND (category_id = 100) AND ((category_id % 10) = 0))"
完璧に動作しますすべてのクエリの条件?
が含まれるようにクエリを変更することであるという結論になってきましたか?私は9.xでパーティション化に関するプランナーにいくつかの改善があったと思う。 –
制約を少し冗長にすることができます: 'CHECK(category_id%10 = 1 AND date_trunc( 'month'、capture_time)= '' 2012-01 -01 ':: date) ' –
@a_horse_with_no_name私は9.1を使用しています – Dojo