Sql server 为什么组合了3个独立查询的TSQL查询运行得慢得多?

Sql server 为什么组合了3个独立查询的TSQL查询运行得慢得多?,sql-server,sql-server-2008,tsql,stored-procedures,Sql Server,Sql Server 2008,Tsql,Stored Procedures,我正在编写一个查询,并在编写过程中分析SQL分析器跟踪,以监控查询的性能和速度 在执行此操作时,我注意到,如果在同一个表上运行3个不同的select,则比在WHERE子句中使用OR将它们分组在一个select中运行要快得多 (A) (B) 以下是两个查询的分析器读数: CPU | Reads | Writes | Duration(ms) A) 15 | 1095 | 0 | 26 B) 531 | 456139 | 0 | 541 你能解释一下吗 非常感谢。三次选择只是三次选择,一次选择

我正在编写一个查询,并在编写过程中分析SQL分析器跟踪,以监控查询的性能和速度

在执行此操作时,我注意到,如果在同一个表上运行3个不同的select,则比在WHERE子句中使用OR将它们分组在一个select中运行要快得多

(A)

(B)

以下是两个查询的分析器读数:

CPU | Reads | Writes | Duration(ms)

A) 15 | 1095 | 0 | 26

B) 531 | 456139 | 0 | 541
你能解释一下吗


非常感谢。

三次选择只是三次选择,一次选择有三个条件,再加上
实际上是选择加上删除重复项的额外成本


如果您确信不会有重复,请考虑使用<代码>联合所有而不是<代码>或。当然,这是一个非常笼统的建议。当仅为了性能而调整查询时,请始终参考执行计划,以查看特定的建议是否适用于您的场景。

三次选择仅为三次选择,一次带有三个条件的选择,加上
实际上是选择加上删除重复项的额外成本


如果您确信不会有重复,请考虑使用<代码>联合所有而不是<代码>或。当然,这是一个非常笼统的建议。当仅为了性能而调整查询时,请始终参考执行计划,以查看特定的建议是否适用于您的场景。

我同意David的观点,但想在其中添加一个代码示例;那些人很可能是个杀手。我教给新开发人员的一条基本规则是,如果你需要一个团队或工会;这与早期过滤的其他基本规律密切相关。在每个联接上进行筛选的查询通常比在where子句中运行的筛选器快几倍,因为优化程序可以看到更好的路由来减少数据

您的查询可能是这样工作的,或者需要其他Union All

Select
    *
From
(
    SELECT * 
    FROM 
        navigation_trees nt  
    WHERE 
        nt.id = @NodeID 

    union 
    SELECT 
        * 
    FROM 
        navigation_trees nt  
    WHERE 
        nt.id = @ParentID 

    union 
    SELECT 
        * 
    FROM 
        navigation_trees nt  
    WHERE
        nt.id IN (SELECT id FROM @ChildrenIDS)

) nt

INNER JOIN 
    contents c 
ON 
    c.navigation_tree_id = nt.id 

我同意David的观点,但我想在其中加入一个代码示例;那些人很可能是个杀手。我教给新开发人员的一条基本规则是,如果你需要一个团队或工会;这与早期过滤的其他基本规律密切相关。在每个联接上进行筛选的查询通常比在where子句中运行的筛选器快几倍,因为优化程序可以看到更好的路由来减少数据

您的查询可能是这样工作的,或者需要其他Union All

Select
    *
From
(
    SELECT * 
    FROM 
        navigation_trees nt  
    WHERE 
        nt.id = @NodeID 

    union 
    SELECT 
        * 
    FROM 
        navigation_trees nt  
    WHERE 
        nt.id = @ParentID 

    union 
    SELECT 
        * 
    FROM 
        navigation_trees nt  
    WHERE
        nt.id IN (SELECT id FROM @ChildrenIDS)

) nt

INNER JOIN 
    contents c 
ON 
    c.navigation_tree_id = nt.id 

是否已尝试显示这两个查询的计划?在SQL Studio中激活执行计划并查看详细信息。表中有多少记录。它将证明读取的正确性。您还可以尝试
WHERE nt.id IN(选择@NodeID UNION ALL选择@ParentID UNION ALL从@ChildrenIDS选择id)
您还可以尝试将
选项(重新编译)
添加到组合查询中。它可能只是有一个更复杂的计划,更容易受到表变量基数为
0
的假设的影响。您是否尝试过为两个查询显示计划?在SQL Studio中激活执行计划并查看详细信息。表中有多少条记录。它将证明读取的正确性。您还可以尝试
WHERE nt.id IN(选择@NodeID UNION ALL选择@ParentID UNION ALL从@ChildrenIDS选择id)
您还可以尝试将
选项(重新编译)
添加到组合查询中。它可能只是有一个更复杂的计划,更容易受到表变量基数为
0
Select
    *
From
(
    SELECT * 
    FROM 
        navigation_trees nt  
    WHERE 
        nt.id = @NodeID 

    union 
    SELECT 
        * 
    FROM 
        navigation_trees nt  
    WHERE 
        nt.id = @ParentID 

    union 
    SELECT 
        * 
    FROM 
        navigation_trees nt  
    WHERE
        nt.id IN (SELECT id FROM @ChildrenIDS)

) nt

INNER JOIN 
    contents c 
ON 
    c.navigation_tree_id = nt.id