postgres前缀索引用法

时间:2017-07-23 14:03:37

标签: postgresql indexing foreign-keys

设置一个主键,一个由3列组成的组合,生成一个索引,可以通过以下方式查看:

select t.relname as tbl, i.relname as idx, a.attname as col
from  pg_class t, pg_class i, pg_index ix, pg_attribute a
where  t.oid = ix.indrelid
and i.oid = ix.indexrelid
and a.attrelid = t.oid
and a.attnum = any(ix.indkey)
and t.relkind = 'r'
and t.relname not like 'pg%'
order by  t.relname, i.relname;

表格是"客户"如TPC-C benchmarking指南中所定义。我的问题是,当在指南中创建外键时,需要创建相应的索引。 鉴于外键的2列与主键的前两列匹配,作为主键约束的一部分生成的索引是否足够?

表&关键DDL:

create table customer (c_id numeric,c_d_id numeric,c_w_id numeric ..);

alter table customer add constraint pk_customer 
primary key (c_w_id, c_d_id, c_id) ;

alter table customer add constraint fk_cust_district
foreign key (c_w_id, c_id) references district (d_w_id, d_id);

问题的原因是在Oracle和SQL Anywhere中,不需要创建索引,并且相应的优化器将使用辅助改进的引用性能的索引,在这种情况下,索引的2列前缀生成为主键约束的一部分。

1 个答案:

答案 0 :(得分:1)

创建表的方式,主键索引不能很好地支持外键约束,因为外键定义的列不是在主键约束定义的开头

主键索引总比没有好:至少可以扫描c_w_idc_id作为过滤器),但不能同时扫描两列,最有效率。

所以PostgreSQL 利用手头的索引,但效率仍然不高。

除非有充分的理由主键列按此顺序定义,否则我建议您在主键定义中交换第二列和第三列。那么索引非常适合外键约束。

如果这不可行,请在(c_w_id, c_id)上创建第二个索引。

(顺便说一句,这在甲骨文上是一样的,除了他们有索引跳过扫描 - 在我看来 - 可疑的优点。)