代码之家  ›  专栏  ›  技术社区  ›  Yishai

除SQL Server之外的数据库引擎是否有这种行为?

  •  0
  • Yishai  · 技术社区  · 14 年前

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

      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
    

    它在预期的参数内再次运行(对于40000多条记录,大约15秒)。这是SQL Server 2005。我的问题的要点是这个特定于SQL Server的“特性”,或者这是RDBMS中的一个常见特性,一般来说:

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

    这看起来像是对SQL Server的咆哮,我想在某种程度上是这样,但我真的想知道其他人是否在Oracle、DB2或任何其他RDBMS中经历过这种情况。虽然我在其他方面有一些经验,但我在SQL Server上只看到过这种容量和复杂性,所以我很好奇其他拥有大型复杂数据库的人在其他产品上是否也有类似的经验。

    2 回复  |  直到 14 年前
        1
  •  4
  •   SQLMenace    14 年前

    可能有几个原因

    1)统计数据是否最新?

    2)您可能遇到参数嗅探问题。

    顺便说一下这种东西

    其中(param2为空或param2=some_view.someColumn2)

    看一看 Do you use Column=@Param OR @Param IS NULL in your WHERE clause? Don't, it doesn't perform

        2
  •  1
  •   mdma    14 年前

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

    但这是查询优化器的一般“特性”。他们会查看您的查询,并尝试对执行速度最快的内容进行知情猜测。作为用户,如果优化器选择(例如)索引扫描或索引查找,我们几乎没有直接控制权,但是可以通过提供表示相同内容的可选方法间接影响它,以查看这是否会调用改进的执行时间。

    如果没有任何其他可能影响查询的模式更改,请检查索引统计信息是否已更新。我们使用每周批量作业来完成这项工作。