【问题标题】:TSQL Optimization - WHERE clause without LIKESQL 优化 - 没有 LIKE 的 WHERE 子句
【发布时间】:2012-10-18 22:41:50
【问题描述】:

针对这种情况最优化的解决方案是什么:

我的查询的 WHERE 子句是这样的:

WHERE columnX LIKE @Account + '%'

我使用 '%' 因为 @Account 可能是 ' ',在这种情况下我想获取所有值。在所有其他情况下,我可以使用等于 (=)。

此解决方案未优化,因为我在 columnX 上有索引,因此我想使用等于 (=)。此外,由于性能原因,使用 OR 的解决方案是不可接受的。

您还有其他建议吗?我尝试在 WHERE 子句中使用 CASE,但没有找到优化的好解决方案。我们的兼容级别是 80,所以不能使用更新的语法。 (不要问为什么:-))

TnX 提前!

内曼加

【问题讨论】:

  • 为什么不能通过 if (@Account ='') 语句将其分成两个部分(查询)?所以如果 @Account='' 你根本不需要 WHERE 子句。
  • 那是一种解决方案,但看起来代码冗余和性能不太好。另外,由于这段代码在程序中,我需要添加 WITH RECOMPILE,因为在两种不同的情况下执行计划不同。
  • 在构建查询的代码中,测试 Account 是否为空或 null,然后重定向以运行查询,该查询显示获取所有行。否则,使用 where columnX = Account。
  • @Eric 你的意思是使用 IF 子句还是其他方式?
  • 您必须发布您的整个函数或过程,以获取有关键入内容的分步说明。

标签: sql sql-server tsql optimization where


【解决方案1】:

你可以试试这个

where columnX = isnull(nullif(@Account, ''), columnX)

【讨论】:

  • 即使这个解决方案并没有提高我的查询性能,这个语法非常有趣和有用!
【解决方案2】:

您正在尝试执行两个语义不同的查询;一个拉所有行,一个拉单行。根据定义,这两个查询将具有两个不同的查询计划。您尝试将它们组合成一个查询以避免“代码重复”是错误的。 “代码重复”不是敌人,复杂性才是。答案是为每个场景创建一个存储过程。这不仅允许每个存储过程代表一个查询计划;您还将按照single responsibility principle 简化您的申请。

【讨论】:

  • 感谢您对代码重复和 SRP 的回答。由于特定情况,我无法创建两个程序,但我将在程序中留下 IF ELSE 并添加 WITH RECOMPILE 以避免执行计划出现问题。
【解决方案3】:

这是我们都面临的情况:)

如果你选择了一个赞,你真的无能为力。你的情况并不是最糟糕的,如果你只在最后加上 %,那么索引很有可能被用于查找。真正的问题是,当您在开始时有 % 时,索引(如果使用)将被扫描

另外,请记住,索引的使用也与您选择的列有关。如果您有一个带有 ID 和名称的表,并在名称上有一个索引,并从中选择 *,则可能不会使用该索引。

最后可以考虑全文搜索,但实现起来比较复杂

【讨论】:

    【解决方案4】:

    在某些版本的 SQL Server 上,如果您使用 OPTION(RECOMPILE),则 OR 不是性能问题。欲了解更多信息,请参阅http://sommarskog.se/dyn-search-2008.html

    【讨论】:

      【解决方案5】:

      试试这个

      DECLARE @var VARCHAR(10) = '' 
      DECLARE @table TABLE ( ID VARCHAR(10) ) 
      
      INSERT INTO @table 
      SELECT '11' 
      UNION 
      SELECT '2' 
      
      SELECT * 
      FROM @table 
      WHERE ( Len(@var) = 0 OR ID = @var ) 
      
      SET @var = '11' 
      
      SELECT * 
      FROM @table 
      WHERE ( Len(@var) = 0 OR ID = @var ) 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-23
        • 2017-08-30
        相关资源
        最近更新 更多