sql-server - 我的 IN 子句导致对 T-SQL 中的索引进行全面扫描。我能做些什么?

标签 sql-server tsql optimization indexing

我有一个带有 50 个参数的 sql 查询,比如这个。

DECLARE
  @p0 int, @p1 int, @p2 int, (text omitted), @p49 int

SELECT
  @p0=111227, @p1=146599, @p2=98917, (text omitted), @p49=125319

--
SELECT
  [t0].[CustomerID], [t0].[Amount],
  [t0].[OrderID], [t0].[InvoiceNumber]
FROM [dbo].[Orders] AS [t0]
WHERE ([t0].[CustomerID]) IN
  (@p0, @p1, @p2, (text omitted), @p49)

预估的执行计划表明,数据库会收集这些参数,对它们进行排序,然后读取索引Orders.CustomerID 从参数最小到最大,然后对记录的其余部分进行书签查找。

问题是最小和最大参数可能相距很远,这可能会导致读取整个索引。

由于这是在客户端的循环中完成的(每次发送 50 个参数,1000 次迭代),这是一个糟糕的情况。我如何制定查询/客户端代码以在不重复索引扫描的情况下获取我的数据,同时减少往返次数?


我考虑过对 50k 参数进行排序,以便出现较小的索引读数。有一个奇怪的缓解情况可以防止这种情况发生——我不能使用这个解决方案。为了模拟这种情况,假设我在任何时候都只有 50 个可用的 ID,并且无法控制它们在全局列表中的相对位置。

最佳答案

将参数插入临时表,然后将其与您的表连接:

DECLARE @params AS TABLE(param INT);

INSERT
INTO    @params
VALUES  (@p1)
...
INSERT
INTO    @params
VALUES  (@p49)

SELECT
  [t0].[CustomerID], [t0].[Amount],
  [t0].[OrderID], [t0].[InvoiceNumber]
FROM @params, [dbo].[Orders] AS [t0]
WHERE ([t0].[CustomerID]) = @params.param

这很可能会在每个循环中使用 NESTED LOOPSINDEX SEEK over CustomerID

关于sql-server - 我的 IN 子句导致对 T-SQL 中的索引进行全面扫描。我能做些什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/687271/

相关文章:

sql - 使用 RAISERROR 指示 ACCESS DENIED 错误

python - 有效地字典列表中的唯一元素

sql - 应该使用哪种数据类型来存储哈希值?

sql-server - 为什么行级锁定在 SQL Server 中似乎无法正常工作?

sql-server - 如何清除 SQL Server 查询缓存?

python - 使用 pyodbc 将 Raspberry Pi 3 连接到 MSSQL Server

Perl 优化器问题 : Will the perl compiler optimize away all of these temporary variables?

javascript - 使用 System.js 的性能问题

SQL Server : Convert varchar to decimal (with considering exponential notation as well)

mysql - 将 MS-SQL 存储过程转换为 MYSQL,但现在由于语法错误而无法创建