参数值过多会减慢查询速度



我有一个在正常情况下运行相当快的查询。但由于筛选器中有多少值,它的运行速度非常慢(在 SSMS 中至少需要 20 分钟(。

这是它的通用版本,您可以看到一个部分正在过滤超过 8,000 个值,使其运行缓慢。

SELECT DISTINCT 
    column 
FROM 
    table_a a 
JOIN 
    table_b b ON (a.KEY = b.KEY)
WHERE 
    a.date BETWEEN @Start and @End
    AND b.ID IN (... over 8,000 values)
    AND b.place IN ( ... 20 values)
ORDER BY 
    a.column ASC

它已经到了太慢而无法在生产应用程序中使用的地步。

有谁知道如何解决这个问题,或优化查询?

若要快速查询,需要索引。您需要为以下列提供单独的索引:a.KEY、b.KEY、a.date、b.ID、b.place。正如 gotqn 之前所写,如果您将 8000 个项目放入临时表并内部联接它,它也会使查询更快,但如果没有联接另一部分的索引,即使这样也会很慢。

您需要

的是将过滤值放在临时表中。然后使用该表通过 INNER JOIN 而不是 WHERE IN 来应用筛选。例如:

IF OBJECT_ID('tempdb..#FilterDataSource') IS NOT NULL
BEGIN;
    DROP TABLE #FilterDataSource;
END;
CREATE TABLE #FilterDataSource
(
    [ID] INT PRIMARY KEY
);
INSERT INTO #FilterDataSource ([ID])
-- you need to split values
SELECT DISTINCT column 
FROM table_a a 
INNER JOIN table_b b 
    ON (a.KEY = b.KEY)
INNER JOIN #FilterDataSource FS
    ON b.id = FS.ID
WHERE a.date BETWEEN @Start and @End
    AND b.place IN ( ... 20 values)
ORDER BY .column ASC;

几个重要注意事项:

  • 我们使用临时表以允许使用并行执行计划
  • 如果您有用于吐痰的快速(例如 CLR 函数(,则可以加入函数本身
  • 使用具有许多值的IN是不好的,SQL Server无法始终构建可能导致超时/内部错误的执行计划 - 您可以在此处找到更多信息

最新更新