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_keyselect * 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 子句过滤器的主要内容,如果未能解决你的问题,请参考以下文章
IServiceProvider.GetServices<T>() 是不是总是按注册顺序返回可用的服务实现?