如何修复此查询(IN子句),以便在数据量较小时SQL服务器性能不会降低?

时间:2016-02-04 00:08:55

标签: sql-server performance

下图显示了一段时间内流程的效果。

Process performance over time

该过程使用以下格式调用存储过程:

CREATE PROCEDURE [dbo].[GetResultSetsAndResultsWhereStatusIsValidatedByPatientId]
    @PatientId uniqueidentifier
AS

BEGIN
    SELECT DISTINCT resultSetTable.ResultSetId,
        resultSetTable.OrderId,
        resultSetTable.ReceivedDateTime,
        resultSetTable.ProfileId,
        resultSetTable.Status,
        profileTable.Code,
        testResultTable.AbnormalFlag,
        testResultTable.Result,
        orderTable.ReceptionDateTime,
        testTable.TestCode,
        orderedProfileTable.[Status] as opStatus
    FROM dbo.ResultSet resultSetTable
        INNER JOIN dbo.[Profile] profileTable on (profileTable.ProfileId = resultSetTable.ProfileId)
        INNER JOIN dbo.[TestResult] testResultTable on (testResultTable.ResultSetId = resultSetTable.ResultSetId)
        INNER JOIN dbo.[Order] orderTable on (resultSetTable.OrderId = orderTable.OrderId)
        INNER JOIN dbo.[Test] testTable on (testResultTable.TestId = testTable.TestId)
        INNER JOIN dbo.OrderedProfile orderedProfileTable on (orderedProfileTable.ProfileId = resultSetTable.ProfileId)
    WHERE orderTable.PatientId = @PatientId
        AND orderedProfileTable.[Status] in ('V', 'REP')
END

问题似乎是IN条款。如果我删除IN子句并仅检查其中一个值,那么我将获得一致的性能,如图的第二部分所示。

AND orderedProfileTable.[Status] = 'V'

该问题似乎也与表格中的数据量有关。只有两个表增长,[ResultSet]和[TestResult],这两个表在性能运行开始时都是空的。

我尝试了以下内容:

  1. 将IN子句移动到外部选择 - 无效
  2. 用连接替换IN子句 - 严重的性能下降
  3. 为"状态"创建索引。 IN子句中使用的字段 - 无效
  4. 即使两个相关表中没有数据,有没有办法始终获得低性能?

2 个答案:

答案 0 :(得分:1)

您是否尝试将IN查询转换为EXIST子句?

WHERE 
    orderTable.PatientId = @PatientId
    AND
    EXISTS
        (SELECT *
        FROM dbo.OrderedProfile as p
        WHERE
            p.profileid = orderedprofiletable.profileid
            AND
            [Status] IN ('v','rep'))

由于你只是在搜索静态结果('v'和'rep'),我认为IN子句本身就是你最好的选择,但EXIST有时可以提高性能,所以值得一试。< / p>

答案 1 :(得分:0)

问题最终与IN子句无关,而是逻辑错误。我们开始质疑为什么查询需要DISTINCT,当我们删除它时,我们在最后一次连接中发现了一个逻辑错误(在匹配的内容中需要更多的标准)。

错误已部分解决,性能问题似乎已得到解决。

Performance

存储过程现在平均在不到10毫秒内完成,并且没有性能下降。