相同的SQL Server查询执行时间不同(其中语句相同但语法不同)

时间:2018-12-24 07:25:29

标签: sql sql-server database performance sql-server-2012

此处显示的两个查询执行时间不同。两者都具有相同的WHERE条件,不同之处仅在于条件语法不同。

第二个查询是从动态查询生成的。

如果您知道相同的原因,请告诉我。

还要让我知道哪个是最适合表现的。

查询#1 (需要1.5秒才能执行)

DECLARE @caseDetailId  VARCHAR(MAX) = '16',
        @patientId VARCHAR(8000) = NULL,
        @isActive NVARCHAR(4000) = NULL,
        @description NVARCHAR(4000) = NULL,
        @clientId VARCHAR(8000) = '1021',
        @machineId VARCHAR(8000) = NULL,
        @oldSystemId VARCHAR(8000) = NULL,
        @isDeleted NVARCHAR(4000) = NULL,
        @userId INT,
        @langId VARCHAR(10) = NULL,
        @page INT = 0,
        @size INT = 0,
        @orderBy VARCHAR(400) = NULL

--Query 1
SELECT * 
FROM CaseDetail 
WHERE 1 = 1
  AND (@isDeleted IS NULL OR [IsDeleted] = @isDeleted)
  AND (@clientId IS NULL OR [ClientId] = @clientId)
  AND (@caseDetailId IS NULL OR [CaseDetailId] IN (SELECT id 
                                                   FROM dbo.Fnsplit(@caseDetailId,',')))
  AND (@patientId IS NULL OR [PatientId] IN (SELECT id 
                                             FROM dbo.Fnsplit(@patientId,',')))
  AND (@isActive IS NULL OR [IsActive] IN (@isActive))
  AND ((@description IS NULL )
        OR (@description IS NOT NULL AND [Description] LIKE  '%'+@description+'%'))

查询#2 (花费0.016秒执行时间):

DECLARE @caseDetailId  VARCHAR(MAX) = '16',
        @patientId VARCHAR(8000) = NULL,
        @isActive NVARCHAR(4000) = NULL,
        @description NVARCHAR(4000) = NULL,
        @clientId VARCHAR(8000) = '1021',
        @machineId VARCHAR(8000) = NULL,
        @oldSystemId VARCHAR(8000) = NULL,
        @isDeleted NVARCHAR(4000) = NULL,
        @userId INT,
        @langId VARCHAR(10) = NULL,
        @page INT = 0,
        @size INT = 0,
        @orderBy VARCHAR(400) = NULL

--Query 2
SELECT * 
FROM CaseDetail 
WHERE 1 = 1
  AND CaseDetail.CaseDetailId IN (SELECT Id FROM dbo.Fnsplit(@CaseDetailId,','))
  AND CaseDetail.ClientId IN (SELECT Id FROM dbo.Fnsplit(@clientId,','))

2 个答案:

答案 0 :(得分:1)

在WHERE条件下的OR子句通常是非常不好的做法,只有少数例外。 SQL Optimizer无法找到使用索引的好的计划,因此,它必须进行全表扫描(读取全表)。 因此,两个提供的查询都有此区别,第二种情况是您报告的速度很好。尝试在WHERE中重新构造第一个没有OR条件的查询,并应解决性能问题。

答案 1 :(得分:1)

您必须知道以下说明:

    在WHERE子句中使用
  1. OR是非常糟糕的做法。
  2. 将值与NULL比较会影响性能。
  3. 带有IN的子查询的执行开销很大。