繁体   English   中英

“使用”命令比使用临时表慢

[英]“With” command slower than using temporary table Select * into #table1 from

为什么以下查询要快得多?

查询1:

    select distinct ID mid
INTO #t1
from A_Position a where a.situationdate=@SituationDate and 
    a.Portfolio_Name=@portfolio and a.Purpose=@purpose and ID!='TOTAL'

select distinct ID gid 
INTO #t2
from B_Position a where a.situationdate=@SituationDate and 
    a.Purpose=@purpose

select @check=COUNT(mid) from #t1 A INNER JOIN #t2 B ON A.mid = 
    B.gid

查询1比查询2快得多。

查询2:

;With 
A as (
select distinct ID mid 
    from A_Position a where 
    a.situationdate=@SituationDate and a.Portfolio_Name=@portfolio and 
    a.Purpose=@purpose and ID!='TOTAL'), 

    B as(
select distinct ID gid 
    from B_Position a where 
    a.situationdate=@SituationDate and a.Purpose=@purpose)

select @check=COUNT(mid) from A INNER JOIN B ON A.mid = 
    B.gid

查询3:

select @check=COUNT(*)  
        from (
    select distinct ID mid 
        from A_Position a where a.situationdate=@SituationDate and 
        a.Portfolio_Name=@portfolio and a.Purpose=@purpose and 
        ID!='TOTAL') A
    inner join (  select distinct ID gid 
        from B_Position a where 
        a.situationdate=@SituationDate and a.Purpose=@purpose) B on mid=gid

基本上,所有三个查询都具有相同的结果,但是查询1只需1-2秒即可执行。 另一方面,查询2或3则需要10多分钟才能执行。 为什么在编写代码的方式上有如此巨大的差异? (为什么“ With”变慢)

这是一个优化问题。 如果查看执行计划,您会明白为什么其中一个比其他计划快得多。

首先,后两个相同。 将子查询表示为CTE或子查询不会更改SQL Server中的执行计划。

为什么临时表版本更快? 简单的答案是,它可以获得更好的执行计划。

但这引出了问题。 原因是由于用于连接两个表的算法。 在CTE /子查询版本中,SQL Server必须猜测生成了多少行。 根据该数字,它选择认为最佳的算法。

在临时表版本中,数据已经在表中,因此SQL Server无需猜测。

因此,临时表可以产生更好的执行计划。 让我告诫一些事情。 使用临时表会产生更多开销-数据实际上需要存储在某个地方。 它还限制了优化的可能性(在这种情况下碰巧是好的,但在其他情况下可能不会)。

您应该能够添加提示以加快其他版本的速度。 我猜像OPTION (HASH JOIN)类的东西。

您也许还可以设置索引来优化所有三个版本。

答案很可能与以下事实有关:第一个查询实际上是三个查询,而其他两个只是一个查询。 不过,您需要查看执行计划以进行确认。

上面的第二个和第三个查询已经提前弄清楚了执行两个子集的内部联接的最佳方法是什么。 但是他们当时不知道这些子集中有多少数据,所以他们有了猜测,在这种情况下,看起来好像他们猜错了,然后选择了一种非常糟糕的方法。 可能已经决定先加入然后进行筛选,或者使用索引或其他方法会更快。 如果查看执行计划,请查找预期行与实际行完全不同的位。

第一个查询将两个子集作为单独的查询放入临时表中。 到进行连接时,它确切知道需要担心多少数据,并且可以选择最佳方法来处理它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM