当前位置:  开发笔记 > 数据库 > 正文

我的IN子句导致在T-SQL中完全扫描索引.我能做什么?

如何解决《我的IN子句导致在T-SQL中完全扫描索引.我能做什么?》经验,为你挑选了1个好方法。

我有一个包含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可用,并且无法控制它们在全局列表中的相对位置.



1> Quassnoi..:

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

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 SEEKCustomerID每个循环.

推荐阅读
Life一切安好
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有