我有一个像这样的存储过程(伪代码)

  storedprocedure param1, param2, param3, param4
  begin
     if (param4 = 'Y')
         begin
             select * from SOME_VIEW order by somecolumn
         end
     else if (param1 is null)
          begin
             select * from SOME_VIEW
                where (param2 is null or param2 = SOME_VIEW.Somecolumn2)
                and (param3 is null or param3 = SOME_VIEW.SomeColumn3) 
             order by somecolumn
          end
     else
          select somethingcompletelydifferent
     end

一切都很好。突然,如果param4为'y',则查询开始永远运行。更改代码:

  storedprocedure param1, param2, param3, param4
  begin
     if (param4 = 'Y')
         begin
             set param2 = null
             set param3 = null
         end
     if (param1 is null)
          begin
             select * from SOME_VIEW
                where (param2 is null or param2 = SOME_VIEW.Somecolumn2)
                and (param3 is null or param3 = SOME_VIEW.SomeColumn3) 
             order by somecolumn
          end
     else
          select somethingcompletelydifferent

并且它再次在预期参数(40,000多个记录)中运行(15秒左右)。这是SQL Server2005。我的问题的要点是SQL Server特定的特定“功能”,或者这是RDBMS中的常见功能:一般而言:

  1. 随着数据的增长而停止工作两年的问题。
  2. “新”执行计划破坏了数据库服务器执行查询的能力,即使在逻辑上等效的替代方案运行正常?

这似乎是对SQL Server的咆哮,我想在某种程度上是对SQL Server的狂欢,但是我确实想知道其他人是否会在Oracle,DB2或任何其他RDBMS上体验这种现实。尽管我在其他方面有一些经验,但我只在SQL Server上看到了这种卷和复杂性,因此我很好奇,如果其他具有大型复杂数据库的其他产品在其他产品中具有相似的经验。

有帮助吗?

解决方案

可能有几个原因

1)统计数据是最新的吗?

2)您可能会遭受参数嗅探

顺便说一句

其中(param2为null或param2 = some_view.somecolumn2)

看一眼 您是否使用column = @param或@param在您的Where子句中为null?不,它不执行

其他提示

我会想象该问题的这个特定实例,并且导致这种情况的所有条件都是SQL Server的特定于SQL Server - 甚至可能是该版本。 (例如SQL Server 2008的行为会有所不同。)

但这是查询优化器的一般“功能”。他们查看您的查询,并试图对最快执行最快执行的明智猜测。作为用户,如果优化器选择(例如)索引扫描或索引寻求索引,我们几乎没有直接控制,但可以通过提供表达同一内容的替代方法来间接影响它,以查看是否可以提高执行时间。

如果没有其他可能影响查询的模式更改,请检查索引统计信息是否已更新。我们使用每周的批处理工作来做到这一点。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top