Oracle中這種技術叫分區裁剪(Partition Pruning),經過排除不須要的分區,只掃描特定分區來極大地優化sql查詢sql
PG中的分區由於經過check約束來實現,所以查詢條件中若是知足某些子分區的約束,就能夠經過排除沒必要要的分區來提升查詢效率oracle
這裏咱們經過執行計劃來看一下pg的這個特性.性能
db01=> show constraint_exclusion; constraint_exclusion ---------------------- partition (1 row) db01=> explain select * from t_partition where log_date = date'2015-3-13'; QUERY PLAN ---------------------------------------------------------------------------------------------- Append (cost=0.00..13.67 rows=7 width=40) -> Seq Scan on t_partition (cost=0.00..0.00 rows=1 width=40) Filter: (log_date = '2015-03-13'::date) -> Bitmap Heap Scan on t_partition_s200503 (cost=4.20..13.67 rows=6 width=40) Recheck Cond: (log_date = '2015-03-13'::date) -> Bitmap Index Scan on idx_t_partition_s200503_1 (cost=0.00..4.20 rows=6 width=0) Index Cond: (log_date = '2015-03-13'::date) (7 rows)
constraint_exclusion參數控制查詢優化器是否使用這種技術.
這裏能夠看到只查詢了t_partition_s200503這個分區測試
不使用此優化手段後的計劃:優化
db01=> set constraint_exclusion=off; SET db01=> explain select * from t_partition where log_date = date'2015-3-13'; QUERY PLAN ---------------------------------------------------------------------------------------------- Append (cost=0.00..65.50 rows=25 width=40) -> Seq Scan on t_partition (cost=0.00..0.00 rows=1 width=40) Filter: (log_date = '2015-03-13'::date) -> Bitmap Heap Scan on t_partition_s200502 (cost=4.20..13.67 rows=6 width=40) Recheck Cond: (log_date = '2015-03-13'::date) -> Bitmap Index Scan on idx_t_partition_s200502_1 (cost=0.00..4.20 rows=6 width=0) Index Cond: (log_date = '2015-03-13'::date) -> Bitmap Heap Scan on t_partition_s200503 (cost=4.20..13.67 rows=6 width=40) Recheck Cond: (log_date = '2015-03-13'::date) -> Bitmap Index Scan on idx_t_partition_s200503_1 (cost=0.00..4.20 rows=6 width=0) Index Cond: (log_date = '2015-03-13'::date) -> Bitmap Heap Scan on t_partition_s200504 (cost=4.20..13.67 rows=6 width=40) Recheck Cond: (log_date = '2015-03-13'::date) -> Bitmap Index Scan on idx_t_partition_s200504_1 (cost=0.00..4.20 rows=6 width=0) Index Cond: (log_date = '2015-03-13'::date) -> Seq Scan on t_partition_s200505 (cost=0.00..24.50 rows=6 width=40) Filter: (log_date = '2015-03-13'::date) (17 rows)
能夠看到優化器選擇的方案是每一個子分區所有掃描一遍,顯而易見性能差距有多大.code
暫時只支持range partition 和 list partition
list 跟 range相似, 好比分公司表按各分公司代碼分區的check 寫法爲 (check branch = '1010100' )it
總得來講pg的分區功能支持類型較少,與oracle相比較實現比較複雜.io
這裏還須要注意:
1. 各子分區見的check約束不要發生數據重疊狀況.
2. 直接更新分區關鍵字,迫使該記錄映射到其餘分區會失敗,須要經過變通方法實現.效率
db01=> select * from t_partition; id | msg | log_date ----+------+------------ 2 | msg2 | 2015-02-13 3 | msg3 | 2015-03-02 4 | msg4 | 2015-04-12 (3 rows) db01=> update t_partition set log_date = date'2015-3-20' where id = 4; ERROR: new row for relation "t_partition_s200504" violates check constraint "t_partition_s200504_log_date_check" DETAIL: Failing row contains (4, msg4, 2015-03-20). db01=> with t as ( db01(> delete from t_partition where id =4 returning * ) db01-> insert into t_partition select t.id,t.msg,date'2015-03-20' from t; INSERT 0 0
或者能夠經過觸發器來實現date
3. 約束排除(Constraint Exclusion)對於諸如now()等不肯定的值不能使用此技術來優化.
db01=> show constraint_exclusion; constraint_exclusion ---------------------- partition (1 row) db01=> explain select * from t_partition where log_date = now(); QUERY PLAN ---------------------------------------------------------------------------------------------- Append (cost=0.00..68.45 rows=25 width=40) -> Seq Scan on t_partition (cost=0.00..0.00 rows=1 width=40) Filter: (log_date = now()) -> Bitmap Heap Scan on t_partition_s200502 (cost=4.20..13.68 rows=6 width=40) Recheck Cond: (log_date = now()) -> Bitmap Index Scan on idx_t_partition_s200502_1 (cost=0.00..4.20 rows=6 width=0) Index Cond: (log_date = now()) -> Bitmap Heap Scan on t_partition_s200503 (cost=4.20..13.68 rows=6 width=40) Recheck Cond: (log_date = now()) -> Bitmap Index Scan on idx_t_partition_s200503_1 (cost=0.00..4.20 rows=6 width=0) Index Cond: (log_date = now()) -> Bitmap Heap Scan on t_partition_s200504 (cost=4.20..13.68 rows=6 width=40) Recheck Cond: (log_date = now()) -> Bitmap Index Scan on idx_t_partition_s200504_1 (cost=0.00..4.20 rows=6 width=0) Index Cond: (log_date = now()) -> Seq Scan on t_partition_s200505 (cost=0.00..27.40 rows=6 width=40) Filter: (log_date = now()) (17 rows)
4. 因爲計劃器進行constraint_exclusion時,對每一個子分區的約束檢查,所以子分區太多會影響解析的性能,官方所說的百八十個性能還能夠我沒有機會測試.不要超過千八百個..
//END