【问题标题】:Planner does not use Check ConstraintsPlanner 不使用检查约束
【发布时间】:2013-10-11 21:07:26
【问题描述】:

请考虑以下对象:

create table invoices_2011 (
  invoice_id bigint not null,
  invoice_date date not null,
  constraint invoice_line_2011_ck1 CHECK (invoice_date >= '2011-01-01' AND 
      invoice_date < '2012-01-01')
);

create table invoices_2012 (
  invoice_id bigint not null,
  invoice_date date not null,
  constraint invoice_line_2012_ck1 CHECK (invoice_date >= '2012-01-01' AND
      invoice_date < '2013-01-01')
);

create table invoices_2013 (
  invoice_id bigint not null,
  invoice_date date not null,
  constraint invoice_line_2013_ck1 CHECK (invoice_date >= '2013-01-01' AND
      invoice_date < '2014-01-01')
);

create or replace view invoices as
select * from invoices_2011
union all 
select * from invoices_2012
union all 
select * from invoices_2013;

如果我查看以下查询的解释计划:

select * from invoices where invoice_date > '2013-10-01';

这表明要扫描的唯一实际物理表是 invoices_2013,这是我所期望的。

但是,当我查看此查询的解释计划时(今天是 10/11/13):

select * from invoices where invoice_date > date_trunc ('month', current_date)

它扫描所有三个表。

有没有人知道有什么方法可以强制检查/插值函数以使检查约束可以利用它?

【问题讨论】:

    标签: postgresql sql-execution-plan check-constraint


    【解决方案1】:

    问题是where 子句必须匹配check constraint。由于date_trunc()current_date 都不是immutable,它们不会在查询中“内联”,这意味着这些函数评估只会在查询执行时发生,在查询计划阶段之后,因此规划器不会知道是否条件匹配check constraint

    为了向规划器提供所需的信息,必须动态构建查询

    create or replace function select_from_invoices(
        _d date
    ) returns setof invoices as $body$
    
    begin
    
    return query execute $$
        select *
        from invoices
        where invoice_date > $1
        $$
        using date_trunc('month', _d)
    ;
    
    end;
    $body$ language plpgsql;
    

    现在只有在date_trunc的结果连接到查询字符串后才会计划查询。

    执行它:

    select *
    from select_from_invoices(current_date);
    

    【讨论】:

      猜你喜欢
      • 2013-12-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-28
      • 2011-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多