使用OR AND的where子句需要花费很长时间才能运行

时间:2019-03-20 15:56:30

标签: sql azure-sql-database

我有以下形式的基本查询:

DECALRE @TestVar int = 0;

SELECT * FROM TestTable     
WHERE
  TestTable.ColA = 1 AND
  (@TestVar = 0
     OR
  (@TestVar = 1 AND TestTable.TestColumn = 'Test')) 

此查询需要30秒才能运行。如果我从以下位置删除:(@TestVar = 1 AND TestTable.TestColumn = 'Test'),则需要1秒钟才能运行。

我认为,如果WHERE子句的第一部分为true,SQL Server将不会评估(@TestVar = 1 AND TestTable.TestColumn = 'Test')

如果不需要,该如何确保不评估条件TestTable.TestColumn = 'Test'

1 个答案:

答案 0 :(得分:1)

在这里重新编译选项是个好选择。

如果您想学习一些东西,可以尝试Dynamic SQL(在Internet上搜索它:))。

    DECLARE @TestVar int = 0;
    DECLARE @TestTable TABLE (TestColumn VARCHAR(50), ColA INT);

    INSERT INTO @TestTable (TestColumn, ColA)
    VALUES ('Test', 1), ('NotTest', 1 ),('Unknown', 1),
           ('Test', 0), ('NotTest', 0 ),('Unknown', 0);

    /* Keeping this one for comparison, just uncomment to check */
    --SELECT * 
    --FROM @TestTable tt
    --WHERE
    --  tt.ColA = 1 AND
    --  (@TestVar = 0
    --     OR
    --  (@TestVar = 1 AND tt.TestColumn = 'Test'));


    DECLARE @sql NVARCHAR(4000);
    DECLARE @parameters NVARCHAR(4000);

    SET @sql = 
    N'DECLARE @TestTable TABLE (TestColumn VARCHAR(50), ColA INT);' +
    N'' +
    N'INSERT INTO @TestTable (TestColumn, ColA)' +
    N'VALUES (''Test'', 1), (''NotTest'', 1 ),(''Unknown'', 1),' +
    N'       (''Test'', 0), (''NotTest'', 0 ),(''Unknown'', 0);' +
    N'' +
    N'SELECT * FROM @TestTable tt WHERE tt.ColA = 1' 

    IF @TestVar = 0
        SET @sql = @sql; /* Do nothing, just adding it for show. @TestVar=0 will always be true */
    IF @TestVar = 1
        SET @sql = @sql + N' AND tt.TestColumn = ''Test'''; /* Only adding the TestColumn check. @TestVar=1 will always be true */
    IF @TestVar NOT IN (0, 1)
        SET @sql = @sql + N' AND 0=1';

    SET @parameters = N'@TestVar INT'

    /* Use this one for checking the statement */
    -- print @sql 

    /* Make sure to use parameterized dynamic sql or you will have security that looks like a Swiss cheese. 
Most tutorials will teach you about this*/
    EXEC sp_executesql @sql, @parameters, @TestVar = @TestVar;