Amy*_*y B 2 t-sql sql-server indexing optimization
我有一个包含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)
Run Code Online (Sandbox Code Playgroud)
估计的执行计划显示数据库将收集这些参数,对它们进行排序,然后从最小参数读取索引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
Run Code Online (Sandbox Code Playgroud)
这将最有可能使用NESTED LOOPS了INDEX SEEK在CustomerID每个循环.
| 归档时间: |
|
| 查看次数: |
881 次 |
| 最近记录: |