首页 > 解决方案 > 如何防止过滤器导致查询运行速度变慢

问题描述

我有以下快速运行的代码(<1s):

SELECT
    [Policy].[Value] AS [PolicyId]
   ,[Person].[Value] AS [PersonId]
   ,[Person].[Index] AS [PersonIndex]
FROM
    [dbo].[View] AS [Policy]
    INNER JOIN [dbo].[ViewPerson] AS [Person] WITH(INDEX([Index])) ON ([Policy].[CollectionId] = [Person].[CollectionId] 
AND [Person].[Name] = 'PersonId' AND [Policy].[Name] = 'PolicyId')
WHERE
    [Policy].[CollectionId] = 10003
    -- AND [Policy].[Value] = [Person].[Value]

这将从我的数据库返回 2 行。当我注释掉最后一行以应用更强大的过滤器时,它只从我的数据库中返回 1 行,但运行时间会更长(约 20 秒)。

有没有一种方法可以减少在应用过滤器时运行此查询所需的时间?理想情况下,我希望它以与原始速度相同的速度运行。

标签: sqltsql

解决方案


您在评论中被告知,强制引擎使用特殊索引 - 在大多数情况下 - 不是最好的主意。该引擎在寻找最佳计划方面非常出色,如果您让它走自己的路,它将发挥最佳作用。

其次,您已经被告知,执行计划是最好的起点。由于我们没有看到任何细节,以下纯属猜测:

如果我理解正确,您的查询将用于CollectionId过滤一个给定的 id(只有很少的 Policy 行)。对于这些行,VIEW 上的 JOIN(我们不知道,后面是什么!)尝试链接人员行。

过滤器应该对一个非常减少的集合起作用。

您的观察让我假设,第二行WHERE正在处理更大的集合。我很确定,在另一个过滤器之后CollectionId=10003拉的过滤器......执行计划将显示细节......

你可以做什么:

  • 去掉索引提示
  • 尝试将 WHERE 中的第二行添加ANDONJOIN 的 - 子句中。

沿着这个:

SELECT
    [Policy].[Value] AS [PolicyId]
   ,[Person].[Value] AS [PersonId]
   ,[Person].[Index] AS [PersonIndex]
FROM
    [dbo].[View] AS [Policy]
    INNER JOIN [dbo].[ViewPerson] AS [Person]  ON ([Policy].[CollectionId] = [Person].[CollectionId] 
                                               AND [Person].[Name] = 'PersonId' 
                                               AND [Policy].[Name] = 'PolicyId'
                                               AND [Policy].[Value] = [Person].[Value])
WHERE
    [Policy].[CollectionId] = 10003;

推荐阅读