IN 子句中的冗余条目

DFo*_*k42 4 performance sql-server t-sql sql-server-2016 query-performance

我有一个带有 where 子句的动态构建查询,如下所示:

where column in ('a', 'a', 'a', 'b')

实际数据要长很多,有很多重复项,如上面的示例中a重复了 3 次。

对于WHERE使用IN具有大量值(其中许多是重复值)的非常大的子句,是否存在潜在的性能影响?

Han*_*non 11

这很容易测试。

USE tempdb;

CREATE TABLE dbo.d
(
    col varchar(1)
);

INSERT INTO dbo.d (col)
VALUES ('a')
    , ('b');
GO
Run Code Online (Sandbox Code Playgroud)

启用“实际”执行计划,然后运行:

SELECT *
FROM dbo.d
WHERE d.col IN ('a', 'b', 'a', 'b', 'c');
Run Code Online (Sandbox Code Playgroud)

结果非常清楚地表明,SQL ServerIN (...)在执行查询之前从子句中消除了重复项。

在此处输入图片说明

请注意,如果IN (...)包含足够多的重复项,则查询的性能可能会比不存在这些重复项时更差。性能不佳的原因可能包括:

  1. 客户端可能难以为IN子句编译项目列表。
  2. 查询优化器花费的时间显然会随着IN子句中项目的增加而有所增加。
  3. 如果查询是通过网络发送的,IN如果需要编译、发送和接收多个 TCP 数据包,子句中的一长串项目可能会导致更高的延迟。

如果查询被非常频繁地发送到服务器,上面列出的项目将被复杂化。

如果列表足够大,单独的文本大小可能会导致其他方面的性能问题,例如编译时间(仅解析事物)和通过网络发送查询。因此,仅仅因为执行计划没有显示它,并不意味着这些附加值不会对性能产生影响。