我有两个分区表,它们具有类似的范围分区(其中DATE_KEY是整数形式的日期--比如9月1日的20230901
,例如:
create table header (
date_key int,
header_key bigint,
other_header_fields character varying(255),
constraint pk_header primary key (date_key, header_key)
) partition by range (date_key);
create table detail (
date_key int,
header_key bigint,
detail_key bigint,
other_detail_fields character varying(255), -- [. . .] more fields
constraint pk_detail primary key (date_key, header_key, detail_key)
) partition by range (date_key);
分区设置为每月范围(即:
create table header_p20230900 partition of header
for values from (20230900) to (20231000);
这些表在组合视图中使用,如下所示:
create view v_record_details as
select
d.date_key,
h.header_key,
h.other_header_fields,
d.detail_key,
d.other_detail_fields
from detail d
inner join header h on d.date_key = h.date_key and d.header_key = h.header_key;
当我从该视图中 Select 时,执行计划本身并不仅限于两个表中所需的分区:
select *
from v_record_details
where date_key = 20230901;
这将限制细节表的分区(可能是因为我从细节表中 Select 了DATE_KEY);但是,在对已分区表进行索引扫描之前,它会对Header表中的所有分区执行seq扫描.
我似乎想不出如何让视图只访问所需的单个分区.有没有办法走出这种困境,而不需要一些愚蠢的东西,比如在两个表中都包含DATE_KEY,并期望用户在两个字段上都设置标准?
我已try 修改该视图以将where h.date_key = d.date_key
包含在该视图中,但没有任何影响.
我还try 在视图的SELECT语句中设置显式条件--当视图的SELECT语句直接使用条件执行时(即:
select
d.date_key,
h.header_key,
h.other_header_fields,
d.detail_key,
d.other_detail_fields
from detail d
inner join header h on d.date_key = h.date_key and d.header_key = h.header_key
where d.date_key = 20230901;
...行为如预期的那样,并且执行计划仅包括来自每个表的正确分区.
只有当写成一种观点时,执行计划才是错误的.
最新情况:
根据Richard Huxton的 comments ,我重新测试并发现,当视图中的SELECT查询在WHERE语句中使用=
时,问题并没有如上所述地发生.只有在try 对一系列日期设置标准时,才会发生这种情况,例如:
select *
from v_record_details
where d.date_key between 20230901 and 20230930
In that case, the select statement itself has the same problem as the view, it is scanning to access all partitions from the header table.