FROM cxfa; (1 row)
其实这个函数是去获取数据字典pg_rewrite(存储为表和视图定义的重写规则),将规则重新算出sql展现给我们。可以通过下面sql去查询数据库保存的重写规则。
aligputf8=# select ev_action from pg_rewrite where ev_class=’v_cxfa’::regclass;
ev_action
————————————————————————————————————————————————————
({QUERY :commandType 1 :querySource 0 :canSetTag true :utilityStmt
<> :resultRelation 0 :into <> :intoOptions <> :intoOnCommit 0 :intoTableSpaceName <> :hasAggs false :hasWindFuncs false :hasSubLinks false :rtable ({RTE :alias {ALIAS :aliasname *OLD* :colnames <>} :eref {ALIAS :aliasname *OLD* :colnames (”a”)} :rtekind 0 :relid 334939 :inh false :inFromCl false :requiredPerms 0 :checkAsUser 0 :forceDistRandom false :pseudocols <>} {RTE :alias
{ALIAS :aliasname *NEW* :colnames <>} :eref {ALIAS :aliasname *NEW* :colnames (”a”)} :rtekind 0 :relid 334939 :inh false :inFromCl false :requiredPerms 0 :checkAsUser 0 :forceDistRandom false :pseudocols <>} {RTE :alias <> :eref {ALIAS :aliasname cxfa :colnames (”a”)} :rtekind 0 :relid 334930 :inh true :inFromCl true :requiredPerms 2 :checkAsUser 0 :forceDistRandom
false :pseudocols <>}) :jointree {FROMEXPR :fromlist ({RANGETBLREF :rtindex
3}) :quals <>} :targetList ({TARGETENTRY :expr {VAR :varno 3 :varattno 1 :vartype 23 :vartypmod -1 :varlevelsup 0 :varnoold 3 :varoattno 1} :resno 1 :resname a :ressortgroupref 0 :resorigtbl 334930 :resorigcol 1 :resjunk
false}) :returningList <> :groupClause <> :havingQual <> :windowClause
<> :distinctClause <> :sortClause <> :limitOffset <> :limitCount <> :rowMarks <> :setOperations <> :resultRelations <> :result_partitions <> :result_aosegnos <> :returningLists <> :intoOidInfo.relOid 0 :intoOidInfo.comptypeOid 0 :intoOidInfo.toastOid 0 :intoOidInfo.toastIndexOid 0 :intoOidInfo.toastComptypeOid 0 :intoOidInfo.aosegOid
0 :intoOidInfo.aosegIndexOid 0 :intoOidInfo.aosegComptypeOid 0}) (1 row)
与pg_get_viewdef类似的函数还有如下,其原理都是差不多的,将数据字典的重写规则翻译为sql:
aligputf8=# \\df pg_get_*def
List of functions
Schema | Name | Result data type | Argument data types
————+—————————+——————+———————–
pg_catalog | pg_get_constraintdef | text oid
pg_catalog | pg_get_constraintdef | text oid, boolean
pg_catalog | pg_get_indexdef | text | oid
pg_catalog | pg_get_indexdef | text | oid, integer, boolean
pg_catalog | pg_get_partition_def | text oid
pg_catalog | pg_get_partition_def | text oid, boolean
pg_catalog | pg_get_partition_rule_def | text pg_catalog | pg_get_partition_rule_def | text boolean
pg_catalog | pg_get_ruledef | text | oid
pg_catalog | pg_get_ruledef | text | oid, boolean pg_catalog | pg_get_triggerdef | text | oid 注:触发器在greenplum里面是不支持的。
| | | | | oid | oid,
5.分区表相关操作
\\d一个表是看不出一个表是否是分区表的,所以必须查询数据字典才能知道。查分区表可以通过pg_partitions跟pg_partition_columns这两个视图来查询,但是这两个视图的结构非常复杂,在线上gp上数据字典都非常大,没有充分利用到索引,这个查询起来效率太低了。我们直接通过数据字典的实体表来查询的话,会快很多。 首先创建一个分区表: create table public.cxfa3(
id integer
,name character varying(20)
,birth date
)Distributed by (id) PARTITION BY range(birth) (
PARTITION p19860801 START (’1986-08-01′::date) END (’1986-08-02′::date) EVERY (’1 day’::interval),
PARTITION p19860802 START (’1986-08-02′::date) END (’1986-08-03′::date) EVERY (’1 day’::interval) );
5.1 查询一个表是否是分区表
表pg_partition:每一个分区表的父表有一行记录。 parkind: 表示分区类型(range 或者 list)。 parnatts: 分区建个数。
paratts: 分区键,跟pg_attribute关联,是一个列表。
表pg_partition_rule:保存分区表每一个子分区的分区名以及分区规则等。
aligputf8=# select count(*) from pg_partition where parrelid=’public.cxfa3′::regclass; count ——- 1 (1 row)
只要count的结果是=1的,表示该表是分区表,否则该表不是分区表。每个分区表在里面只有一行记录。
5.2 查询一个表的分区键
aligputf8=# select attname as columnname
aligputf8-# from pg_attribute a,pg_partition b aligputf8-# where a.attnum = b.paratts[0] aligputf8-# and b.parrelid = a.attrelid
aligputf8-# and a.attrelid=’public.cxfa3′::regclass; columnname ———— birth (1 row)
由于现在gp上面的分区键都是一个的,所以为了效率,我们也只是获取第一个分区键
5.3 查询分区表每个分区的具体信息
aligputf8=# SELECT
pp.parrelid::regclass,pr1.parchildrelid::regclass,pr1.parname, aligputf8-# CASE
aligputf8-# WHEN pp.parkind = ‘h’::”char” THEN ‘hash’::text
aligputf8-# WHEN pp.parkind = ‘r’::”char” THEN ‘range’::text
aligputf8-# WHEN pp.parkind = ‘l’::”char” THEN ‘list’::text
aligputf8-# ELSE NULL::text aligputf8-# END AS partitiontype,
aligputf8-# pg_get_partition_rule_def(pr1.oid, true) AS partitionboundary
aligputf8-# FROM pg_partition pp, pg_partition_rule pr1
aligputf8-# WHERE pp.paristemplate = false AND pp.parrelid = ‘cxfa3′::regclass AND pr1.paroid = pp.oid
aligputf8-# order by pr1.parname;
parrelid | parchildrelid | parname | partitiontype
| partitionboundary
———-+———————–+———–+—————+—————————————————————————————————
cxfa3 | cxfa3_1_prt_p19860801 | p19860801 | range |
PARTITION p19860801 START (’1986-08-01′::date) END (’1986-08-02′::date) EVERY (’1 day’::interval)
cxfa3 | cxfa3_1_prt_p19860802 | p19860802 | range |
PARTITION p19860802 START (’1986-08-02′::date) END (’1986-08-03′::date) EVERY (’1 day’::interval) (2 rows)