使用 WHERE 子句中的过滤器优化 OUTER JOIN 查询。(查询规划器)

Posted

技术标签:

【中文标题】使用 WHERE 子句中的过滤器优化 OUTER JOIN 查询。(查询规划器)【英文标题】:Optimizing OUTER JOIN queries using filters from WHERE clause.(Query Planner) 【发布时间】:2020-05-13 10:59:15 【问题描述】:

我正在编写一个分布式 SQL 查询计划器(查询引擎)。数据将从涉及网络 I/O 的 RDBMS(PostgreSQL) 节点获取。

我想优化 JOIN 查询。

执行的逻辑顺序是:

    做JOIN(利用ON子句) 对连接的结果应用 WHERE 子句。

我正在考虑先应用过滤器(特定于表的 WHERE 子句)本身,然后再加入。 在什么情况下会导致错误的结果?


例子:

SELECT * 
FROM tableA 
LEFT JOIN tableB ON(tableA.col1 = tableB.col1) 
LEFT JOIN tableC ON(tableB.col2 = tableC.col1)
WHERE tableA.colY < 100 AND tableB.colX > 50 

逻辑执行:

    joinResult = (tableA left join tableB ON() ) left join tableC ON() 使用给定的 WHERE 子句过滤 joinResult。

建议执行:

    filteredA = tableA WHERE tableA.colY

    filteredB = tableB WHERE tableB.colX > 50

    结果 = (filteredA left join filteredB ON(..))left join tableC ON(..)

我可以像这样优化任何查询吗?那就是先过滤表,然后在上面应用连接。

编辑: 有些人在谈论这个具体的例子时感到困惑和谈论。我不是在谈论这个特定的示例查询,我正在编写一个查询计划器,我想处理所有类型的查询

请注意,每个表都被分片存储在不同的机器上,当前的执行模型是获取每个表然后在本地进行连接。因此,如果我在获取之前应用 WHERE 过滤器,那就更好了。

【问题讨论】:

您的 where 子句正在将第一个 left join 转换为内部连接。 这只是一个例子,WHERE 子句可能根本不存在。反正我已经编辑过了 Logical Order of Execution is: 错误。没有逻辑顺序。只要结果正确,什么都可以。 @Insaf:这是语句的解析顺序,而不是实际的执行顺序 如果你正在编写自己的 DBMS,那么这与 PostgreSQL 有什么关系? 【参考方案1】:

这其实是一个复杂的话题。

在某些情况下,我们可以过滤表格。我们还可以重新排序外部连接,然后将过滤器 quals 推入内部。

我正在阅读有关此的研究论文,但我还没有完成(可能也没有完成)。

所以现在,对于那些正在寻找答案的人,您可能可以阅读这篇研究论文,尤其是第 2.2 节。 http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.43.2531&rep=rep1&type=pdf


目前,我依赖 PostgreSQL 的规划器并获取其输出并根据我的要求重构查询。

【讨论】:

以上是关于使用 WHERE 子句中的过滤器优化 OUTER JOIN 查询。(查询规划器)的主要内容,如果未能解决你的问题,请参考以下文章

使用 INCLUDE 索引 OUTER/CROSS APPLY 的 WHERE 子句

SQL 优化 where 子句中的条件

Linq-to-Entities:带有 WHERE 子句和投影的 LEFT OUTER JOIN

sql优化

oracle 性能优化建议

Oracle查询性能优化