Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用或联接-查询计划器选择嵌套循环_Sql_Sql Server_Rdbms_Query Planner - Fatal编程技术网

Sql 使用或联接-查询计划器选择嵌套循环

Sql 使用或联接-查询计划器选择嵌套循环,sql,sql-server,rdbms,query-planner,Sql,Sql Server,Rdbms,Query Planner,我想知道为什么MSSQLServerQueryPlanner创建嵌套循环,而不是选择一个联合来连接或条件 注意:从搜索开始,似乎不是特定于MSSQL的 例如 在我的情况下需要6分钟(两个表上的1和2都有索引) 但是 需要2秒钟 我知道为什么第一个需要这么长时间(因为嵌套循环,两个联合使用索引),但我想知道为什么查询规划器不选择联合作为执行计划 在使用未使用它的UNION时,是否有一些需要注意的警告 为什么查询计划器中没有实现此逻辑 这仅仅是为了让查询计划器的代码更简单(因为它可能已经相当复杂),

我想知道为什么MSSQLServerQueryPlanner创建嵌套循环,而不是选择一个联合来连接或条件

注意:从搜索开始,似乎不是特定于MSSQL的

例如

在我的情况下需要6分钟(两个表上的1和2都有索引)

但是

需要2秒钟

我知道为什么第一个需要这么长时间(因为嵌套循环,两个联合使用索引),但我想知道为什么查询规划器不选择联合作为执行计划

在使用未使用它的UNION时,是否有一些需要注意的警告

为什么查询计划器中没有实现此逻辑


这仅仅是为了让查询计划器的代码更简单(因为它可能已经相当复杂),还是因为他们没有时间进行优化,还是因为我没有意识到其他一些警告?

这是一个选择性问题吗?SQL Server希望索引具有高度选择性。一个谓词总是被认为比两个谓词或更具选择性,在您的情况下,差异可能是使用索引与不使用索引之间的差异


请参阅巴特·邓肯(Bart Duncan)的SQL博客,了解有关选择性的长篇文章。

@RhysJones是非常正确的,有时使用索引会降低速度,因为如果使用非聚集索引,它仍然必须在聚集索引中搜索数据。是的,选择性在这里起了作用。另一个问题可能更普通,但统计数据可能已经过时。统计数据上次是什么时候更新的?这些查询不是等价的。如果
TableA
TableB
包含它们自己的重复项,第一个查询将返回它们,第二个查询将不返回它们。优化器通常无法将一个文件重写为另一个文件。@jeroen它只能使用rid作为重复数据发生器,因为它在某些情况下已经这样做了@MartinSmith:nice find。正如该页所提到的,这些查询实际上并不等同,但优化器可以做类似于#2的事情来实现#1。@Namphibian我们启用了自动更新统计信息,但我们也在一夜之间运行更新统计信息100。(不是我的选择)这是另一件我确实想知道它是否值得做的事情,因为更新统计工作每晚要花一个多小时来完成,这绝对会消耗磁盘IO/CPU。
SELECT * FROM TableA a
JOIN TableB b
ON a.One = b.One 
OR a.Two = b.Two
SELECT * FROM TableA a
JOIN TableB b
ON a.One = b.One

UNION -- Not ALL, as need to remove duplicates

SELECT * FROM TableA a
JOIN TableB b
ON a.Two = b.Two