本文為您介紹分區剪枝樣本,以便您掌握使用分區剪枝。
樣本:SELECT
EXPLAIN語句用於顯示語句的執行計畫。您可以使用EXPLAIN語句來確認是否從查詢的執行計畫中剪去分區。
- 首先,建立一張簡單表:
CREATE TABLE sales ( dept_no number, part_no varchar2, country varchar2(20), date date, amount number ) PARTITION BY LIST(country) ( PARTITION europe VALUES('FRANCE', 'ITALY'), PARTITION asia VALUES('INDIA', 'PAKISTAN'), PARTITION americas VALUES('US', 'CANADA') );
- 然後,執行包含
EXPLAIN
語句的約束查詢:EXPLAIN (COSTS OFF) SELECT * FROM sales WHERE country = 'INDIA';
查詢計劃結果如下,伺服器將只掃描表sales_asia,country值為INDIA的記錄將會儲存到該表中:postgres=# EXPLAIN (COSTS OFF) SELECT * FROM sales WHERE country = 'INDIA'; QUERY PLAN --------------------------------------------------- Append -> Seq Scan on sales Filter: ((country)::text = 'INDIA'::text) -> Seq Scan on sales_asia Filter: ((country)::text = 'INDIA'::text) (5 rows)
- 可執行如下查詢,搜尋與未包括在分區鍵中的值匹配的記錄:
EXPLAIN (COSTS OFF) SELECT * FROM sales WHERE dept_no = '30';
查詢計劃結果如下,伺服器將查詢所有的分區,從而定位滿足查詢的記錄:postgres=# EXPLAIN (COSTS OFF) SELECT * FROM sales WHERE dept_no = '30'; QUERY PLAN ----------------------------------------- Append -> Seq Scan on sales Filter: (dept_no = 30::numeric) -> Seq Scan on sales_europe Filter: (dept_no = 30::numeric) -> Seq Scan on sales_asia Filter: (dept_no = 30::numeric) -> Seq Scan on sales_americas Filter: (dept_no = 30::numeric) (9 rows)
- 排除約束在查詢子分區表時同樣適用:
CREATE TABLE sales ( dept_no number, part_no varchar2, country varchar2(20), date date, amount number ) PARTITION BY RANGE(date) SUBPARTITION BY LIST (country) ( PARTITION "2011" VALUES LESS THAN('01-JAN-2012') ( SUBPARTITION europe_2011 VALUES ('ITALY', 'FRANCE'), SUBPARTITION asia_2011 VALUES ('PAKISTAN', 'INDIA'), SUBPARTITION americas_2011 VALUES ('US', 'CANADA') ), PARTITION "2012" VALUES LESS THAN('01-JAN-2013') ( SUBPARTITION europe_2012 VALUES ('ITALY', 'FRANCE'), SUBPARTITION asia_2012 VALUES ('PAKISTAN', 'INDIA'), SUBPARTITION americas_2012 VALUES ('US', 'CANADA') ), PARTITION "2013" VALUES LESS THAN('01-JAN-2014') ( SUBPARTITION europe_2013 VALUES ('ITALY', 'FRANCE'), SUBPARTITION asia_2013 VALUES ('PAKISTAN', 'INDIA'), SUBPARTITION americas_2013 VALUES ('US', 'CANADA') ) );
當您查詢這張表時,查詢計劃器會從搜尋路徑中剪去任何可能不包含您想要的結果集的分區或子分區。postgres=# EXPLAIN (COSTS OFF) SELECT * FROM sales WHERE country = 'US' AND date = 'Dec 12, 2012'; QUERY PLAN ----------------------------------------------------------------------------- Append -> Seq Scan on sales Filter: (((country)::text = 'US'::text) AND (date = '12-DEC-12 00:00:00'::timestamp without time zone)) -> Seq Scan on sales_2012 Filter: (((country)::text = 'US'::text) AND (date = '12-DEC-12 00:00:00'::timestamp without time zone)) -> Seq Scan on sales_americas_2012 Filter: (((country)::text = 'US'::text) AND (date = '12-DEC-12 00:00:00'::timestamp without time zone)) (7 rows)
樣本:UPDATE、DELETE
分區表支援update、delete在執行器期間(runtime)執行分區剪枝。
- 執行以下命令,建立一張表。
create table t1_hash (id int , value int) partition by hash(id) partitions 4;
- 執行以下命令,進行update操作。
postgres=# explain update t1_hash set value = value+1 where id = least(1,2); QUERY PLAN ------------------------------------------------------------------------- Update on t1_hash (cost=0.00..92.18 rows=24 width=14) Update on t1_hash_p1 Update on t1_hash_p2 t1_hash -> Append (cost=0.00..92.18 rows=24 width=14) Subplans Removed: 1 -> Seq Scan on t1_hash_p1 (cost=0.00..46.03 rows=12 width=14) Filter: (id = LEAST(1, 2)) (7 rows)
- 執行以下命令,進行delete操作。
postgres=# explain delete from t1_hash where id = least(1,2); QUERY PLAN ------------------------------------------------------------------------- Delete on t1_hash (cost=0.00..92.12 rows=24 width=10) Delete on t1_hash_p1 Delete on t1_hash_p2 t1_hash -> Append (cost=0.00..92.12 rows=24 width=10) Subplans Removed: 1 -> Seq Scan on t1_hash_p1 (cost=0.00..46.00 rows=12 width=10) Filter: (id = LEAST(1, 2)) (7 rows)