我有以下形式的基本查询:
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'
?
答案 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;