postgresql中表的继承及分区表(四)
2019獨角獸企業重金招聘Python工程師標準>>>
分區查詢優化-Constraint Exclusion
Oracle中這種技術叫分區裁剪(Partition Pruning),通過排除不需要的分區,只掃描特定分區來極大地優化sql查詢
PG中的分區因為通過check約束來實現,因此查詢條件中如果滿足某些子分區的約束,就可以通過排除不必要的分區來提高查詢效率
這里我們通過執行計劃來看一下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)可以看到優化器選擇的方案是每個子分區全部掃描一遍,顯而易見性能差距有多大.
PG支持的分區類型
暫時只支持range partition 和 list partition
list 跟 range類似, 比如分公司表按各分公司代碼分區的check 寫法為 (check branch = '1010100' )
分區總結
總得來說pg的分區功能支持類型較少,與oracle相比較實現比較復雜.
這里還需要注意:
1. 各子分區見的check約束不要發生數據重疊情況.
2. 直接更新分區關鍵字,迫使該記錄映射到其他分區會失敗,需要通過變通方法實現.
或者可以通過觸發器來實現
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
轉載于:https://my.oschina.net/hippora/blog/379754
總結
以上是生活随笔為你收集整理的postgresql中表的继承及分区表(四)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么Nginx性能比Apache高
- 下一篇: 中西医与算法之间的联系