是否对LEFT JOIN子查询表参数进行了多次评估?

时间:2009-05-12 09:52:34

标签: sql mysql

我有一个如下所示的查询:

SELECT  *
FROM    employees e
LEFT JOIN
        (
        SELECT  *
        FROM    timereports
        WHERE   date = '2009-05-04'
        ) t
ON      e.id = t.employee_id

如您所见,我的LEFT JOIN第二个表参数是由子查询生成的。

db是仅评估此子查询一次还是多次?

感谢。 马蒂

4 个答案:

答案 0 :(得分:2)

这取决于RDBMS

在大多数情况下,将使用HASH OUTER JOIN,在这种情况下,子查询将被评估一次。

另一方面,

MySQL无法生成HASH JOIN,这就是为什么它最有可能将谓词推入子查询并发出此查询:

SELECT  *
FROM    timereports t
WHERE   t.employee_id = e.id
        AND date = '2009-05-04'

在嵌套循环中。如果您有timereports (employee_id, date)的索引,这也会很有效。

答案 1 :(得分:0)

如果您使用的是SQL Server,则可以查看查询的Execution Plan。 SQL Server查询优化器将优化查询,以便花费最少的时间执行。最佳时间将基于某些条件即。索引等。

答案 2 :(得分:0)

您必须要求数据库显示该计划。执行此操作的算法是基于许多因素动态地(在查询时)选择的。某些数据库使用密钥分发的统计信息来决定使用哪种算法。其他数据库有相对固定的规则。

此外,每个数据库都有一个不同算法的菜单。数据库可以使用排序合并算法或嵌套循环。在这种情况下,可能存在查询展平策略。

您需要使用数据库独特的“解释计划”功能来查看查询执行计划。

您还需要知道您的数据库是否使用提示(通常是SQL中嵌入的注释)来选择算法。

您还需要知道您的数据库是否使用统计信息(有时称为“基于成本的查询优化器”)来选择算法。

您知道所有这些,您将知道您的查询是如何执行的,以及内部查询是多次评估还是扁平化为父查询或评估一次以创建父查询使用的临时结果。

答案 3 :(得分:0)

评价是什么意思?

数据库有几个不同的选项如何执行连接,两个最常见的选项是

  • 嵌套循环,在这种情况下,一个表中的每一行都将循环通过,另一个表中的相应行将被查找,并且
  • 散列连接,这意味着两个表将被扫描一次,然后使用一些散列算法合并结果。

选择这两个选项中的哪一个取决于数据库,表的大小和可用的索引(以及可能的其他选项)。