我有一个包含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 LOOPS
了INDEX SEEK
在CustomerID
每个循环.