我刚刚替换了一个看起来像这样的SQL语句:
SELECT UserID, sUserName, sFirstName + ' ' + sLastName as [Name], iSiteNumber
FROM DecimalUsers left join dbo.CustomerSitePermissions on UserID = iUserID
WHERE
(cast(iSiteNumber as nvarchar(50)) like '%' + @query + '%' and (iPermissionIndex = 2 or iPermissionIndex = 0) and (bPrimarySite = 'true' or UserID in
(SELECT top 1 iUserID FROM CustomerSitePermissions where iUserID not in
(SELECT iUserID FROM CustomerSitePermissions WHERE bPrimarySite = 'true'))))
OR CAST(sUserName as NVARCHAR(50)) LIKE @query + '%'
OR CAST(sFirstName as NVARCHAR(50)) LIKE @query + '%'
OR CAST(sLastName as NVARCHAR(50)) LIKE @query + '%';
它运行得非常慢(每个查询大约15秒)。也许它是WHERE
语句的第一部分,带有丑陋的嵌套查询。果然,取下它会把时间缩短到不到一秒钟。结案!
当您删除第一个where条件时,查询不仅会加速,而且如果您删除了所有其他条件,也会加快查询速度。检查sUserName
,sFirstName
和sLastName
,但不 iSiteNumber
在一秒钟内完成。同样,检查iSiteNumber
,但不 sUserName
,sFirstName
或sLastName
也会在一秒钟内完成。如果iSiteNumber
检查和任何其他检查(并不重要哪一项或多少项),查询速度很慢。
关于此查询的某些内容比其各部分的总和要慢。为什么呢?
答案 0 :(得分:1)
然而,确保你有适当的指数
在您的iSiteNumber中 您正在为in子句使用多个subselect,这会强制db引擎重复访问数据..
对于其他部分,每个OR子句意味着重复访问日期
可能是你可以重写你的查询,避免这些tecnique
例如,而不是在bPrimarySite =' true'
( SELECT top 1 iUserID
FROM CustomerSitePermissions where iUserID not in
(SELECT iUserID
FROM CustomerSitePermissions WHERE bPrimarySite = 'true'
)
)
您可以使用内部联接来反转逻辑查询或简化查询,例如:
( SELECT top 1 iUserID
FROM CustomerSitePermissions where
bPrimarySite = 'false'
)
并且您可以尝试重写您的查询以避免IN子句的上部子选择并使用内部联接..如果可能的话。
根据您真正需要的真实逻辑和结果,这些建议可能有用或无用