0

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

  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 Server 2005 的问题。我的问题的要点是 SQL Server 特有的这个特殊“功能”,或者这是 RDBMS 中的一个常见功能,一般来说:

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

这似乎是对 SQL Server 的咆哮,我想在某种程度上确实如此,但我真的很想知道其他人是否在使用 Oracle、DB2 或任何其他 RDBMS 时体验过这种现实。虽然我和别人有过一些经验,但是我只在SQL Server上看到过这种体积和复杂度,所以我很好奇其他拥有大型复杂数据库的人是否在其他产品中也有类似的经验。

4

2 回答 2

4

可能有几个原因

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

2)您可能正在遭受参数嗅探

顺便说一句,这种东西

其中(param2 为 null 或 param2 = SOME_VIEW.Somecolumn2)

看看你在 WHERE 子句中使用 Column=@Param OR @Param IS NULL 吗?不要,它不执行

于 2010-05-27T23:09:14.757 回答
1

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

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

如果没有任何其他可能影响查询的架构更改,则检查索引统计信息是否已更新。我们使用每周批处理作业来执行此操作。

于 2010-05-27T23:10:07.567 回答