参数值太多会降低查询速度

时间:2017-05-15 22:52:13

标签: sql-server tsql optimization ssms

我的查询在正常情况下运行得相当快。但由于过滤器中有多少值,它运行速度非常慢(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

在生产应用程序中使用它太慢了。

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

2 个答案:

答案 0 :(得分:1)

您需要将过滤值放在临时表中。然后使用该表格使用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无法始终构建可能导致超时/内部错误的执行计划 - 您可以找到更多信息here

答案 1 :(得分:1)

要快速进行查询,您需要索引。 您需要以下列的单独索引:a.KEY,b.KEY,a.date,b.ID,b.place。 正如之前写过的getqn,如果你将8000个项目放到临时表中,并且内部连接它,它也会使查询更快,但是如果连接的另一部分没有索引,那么即使这样也会很慢。