优化:一次性 vs 分期

OMG*_*ies 6 sql-server-2005 sql-server

我遇到了两种选择的情况:

  1. 使用成本约为 0.07 的单个查询

    INSERT INTO @vals
    SELECT ...
      FROM ...
      JOIN ... 
      JOIN ...
     WHERE a.col = 1 OR b.col IS NOT NULL
    
    Run Code Online (Sandbox Code Playgroud)
  2. 使用两个查询得到相同的结果——第一个成本 ~0.05,第二个成本 ~0.3

    INSERT INTO @temp
    SELECT ...
      FROM ...
      JOIN ...
    
    INSERT INTO @vals
    SELECT ...
      FROM @temp
      JOIN ...
     WHERE a.col = 1
    UNION ALL
    SELECT ...
      FROM @temp
      JOIN ...
      JOIN ...
     WHERE b.col IS NOT NULL
    
    Run Code Online (Sandbox Code Playgroud)

我选择了第一个选项 - 单个查询,因此不必担心在查询之间更改数据并降低总体成本。这是谨慎的选择吗?

这是针对最初需要约 5 分钟以上的操作,在我们的应用程序中超时。使用具有唯一聚集索引的表变量,重写使该时间始终缩短到 1.5 分钟。

And*_*mar 3

一个和两个查询之间的差异可能没有您想象的那么大。例如,比较以下查询:

declare @t table (id int)
insert into @t select id from Table1 where col1 = 7
update Table1 set col2 = 8 where id in (select id from @t)
Run Code Online (Sandbox Code Playgroud)

对于这个查询:

update Table1 set col2 = 8 where id in (select id from Table1 where col1 = 7)
Run Code Online (Sandbox Code Playgroud)

对于第二个查询,SQL Server 可以先运行子查询,并将结果存储在临时表中。如果这样做的话,这将与执行第一个查询的方式完全相同!

因此,将查询一分为二的效果是限制了查询优化器的选择。第一个查询要求子查询在更新之前执行。第二个查询让优化器可以自由地获取一行,然后更新表,然后获取下一行。

现在,当您升级硬件、SQL Server 版本或数据库发生更改时,您最好重新验证您的限制实际上是否有益。那有点贵。

因此,我宁愿不拆分查询,或强制执行查询计划,除非费用可以被相当大的优势所抵消。对我来说,从 0.07 秒到 0.3 秒看起来差别不大,除非查询每分钟左右运行一次以上。