postgres:是不是按返回顺序应用 where 子句过滤器

Posted

技术标签:

【中文标题】postgres:是不是按返回顺序应用 where 子句过滤器【英文标题】:postgres: does where clause filters applied in order they returnpostgres:是否按返回顺序应用 where 子句过滤器 【发布时间】:2021-02-04 14:08:13 【问题描述】:

以下是查询在 where 条件下有 3 个过滤器,哪个过滤器首先应用于表?过滤器是否按照查询中从右到左的顺序应用于表。

我希望先过滤掉 product_key,然后过滤掉剩余的过滤器。

select *
from order_history
where product_key in (select product_key from products
                      where status = 'avilable' )
  and province = 'Texas'
  and category_key in (3,4,5)

【问题讨论】:

优化器决定顺序。 我们不能强制执行,还是我们可以选择先使用 product_key,因为我想在过滤后的 product_key 中使用 category_key 和省 我相信下面是一种方法,我们可以先过滤product_key select * from order_history h inner join (select product_key from products where status = 'avilable' ) p on h.product_key =p.product_key where province = 'Texas' and category_key in (3,4,5) 相信优化器,不要试图愚弄它。编写简单的 SQL 以便于优化。 确保统计数据是最新的。 【参考方案1】:

首先在表格上应用哪个过滤器?

如评论中所述,优化器确定顺序。它应该以一种知情的方式这样做——我假设不断的比较将在in 之前进行。其中一些可能会转换为索引。

您可以使用case 表达式坚持自己的排序:

select oh.*
from order_history oh
where (case when province is distinct from 'Texas' then false
            when category_key not in (3, 4, 5) then false
            else product_key in (select product_key
                                 from products
                                 where status = 'available'
                                )
       end);

我强烈建议您永远不要使用这种方法,因为它会阻止优化器选择更好的执行计划——例如,查询不会使用索引或分区。

但是,case 表达式确实按顺序评估条件,因此您可以坚持使用这种结构的特定顺序。

【讨论】:

【参考方案2】:

首先在表上应用哪个过滤器?过滤器是否按照查询中从右到左的顺序应用于表。

由于“AND”是可传递的,所以顺序没有意义。这就像说“1+2”与“2+1”一样。 “x=1 and y=2”等价于“y=2 and x=1”。这与 C/C++ 中的运算符 && 不具有传递性不同:“if(pointer && *pointer)”首先测试指针是否为空,这是您想要的,并且与“if(*pointer && pointer)”完全不同" 如果指针为空,将会崩溃。

优化器将尝试按照它认为可以提供最佳性能的顺序应用条件。这通常意味着首先选择最具选择性的可转位条件。例如,如果 "province='Texas'" 只选择表的 1%,并且上面有一个索引,那么首先使用它并且只将其余过滤条件应用于 1%通过第一个过滤器的行。如果表统计信息是最新的(运行 VACUUM ANALYZE),优化器通常会提供非常好的选择。

【讨论】:

以上是关于postgres:是不是按返回顺序应用 where 子句过滤器的主要内容,如果未能解决你的问题,请参考以下文章

Rails Postgres 查询无法返回新记录

Postgres维护的正确顺序

IServiceProvider.GetServices<T>() 是不是总是按注册顺序返回可用的服务实现?

对 Redshift/Postgres 中的两个矛盾条件使用 WHERE EXISTS 语句?

按添加的 WHERE 条件的顺序对 SQL 输出进行排序

在 django(postgres 后端)中按数字字符串排序查询结果