postgresql中表的繼承及分區表(四)

分區查詢優化-Constraint Exclusion

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

PG支持的分區類型

暫時只支持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

相關文章
相關標籤/搜索