具有互斥性能的SQL条件

时间:2018-03-16 15:17:55

标签: sql sql-server-2012 subquery query-performance

我刚刚替换了一个看起来像这样的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条件时,查询不仅会加速,而且如果您删除了所有其他条件,也会加快查询速度。检查sUserNamesFirstNamesLastName,但 iSiteNumber在一秒钟内完成。同样,检查iSiteNumber,但 sUserNamesFirstNamesLastName也会在一秒钟内完成。如果iSiteNumber检查和任何其他检查(并不重要哪一项或多少项),查询速度很慢。

关于此查询的某些内容比其各部分的总和要慢。为什么呢?

1 个答案:

答案 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子句的上部子选择并使用内部联接..如果可能的话。

根据您真正需要的真实逻辑和结果,这些建议可能有用或无用