SQL Server 查询处理器耗尽内部资源

问题描述 投票:0回答:4

查询:

update mytable 
    set mycol = null
    where id in (
        583048,
        583049,
        ... (50000 more)
)

留言:

查询处理器耗尽了内部资源,无法 生成查询计划。这是一个罕见的事件,仅预计 极其复杂的查询或引用非常大的查询 表或分区的数量。请简化查询。如果你 认为您错误地收到此消息,请联系客户 支持服务了解更多信息。

我的查询很简单, 我应该怎么写才能正常工作?

sql-server t-sql
4个回答
24
投票

将值列表插入到

#temp
表中,然后使用
in

正如在这个答案中所解释的那样大量的

IN
值可能会导致它在扩展到
OR

时耗尽堆栈

另请参阅相关连接项目


0
投票

如果您在 SQL Server 2016 或更高版本中发现此错误,请尝试将数据库兼容性级别更改为较低版本 120 或 110 等。(link)


0
投票

有一个简单的解决方法,拆分你的谓词 替换这个

SELECT * FROM TABLE
WHERE ID like (1,2,3, ... 10000)

SELECT * FROM TABLE
WHERE ID like (1,2,3, 999) OR 
ID like (1000, .. 1999) OR 
... OR 
ID like (9000, .. 10000)

我在 EF 中遇到此错误,并使用 linqkit 1.2.4 包修复了它。我换了

query.Table.Where(t => ids.contains(id))

var dividedIds = DivideArray(ids.ToArray());
foreach (var batchPortalIds in dividedPortalIds)
{
     predicate.Or(s => batchPortalIds.Contains(s.PortalId.Value));
}

其中 DivideArray 是将单个数组转换为数组列表的函数

    private List<int[]> DivideArray(int[] originalArray)
        {
            int batchSize = 1000;
    
            List<int[]> dividedArrays = new List<int[]>();
            int currentIndex = 0;
    
            while (currentIndex < originalArray.Length)
            {
                int batchSizeRemaining = Math.Min(batchSize, originalArray.Length - currentIndex);
                int[] batch = new int[batchSizeRemaining];
    
                Array.Copy(originalArray, currentIndex, batch, 0, batchSizeRemaining);
                dividedArrays.Add(batch);
    
                currentIndex += batchSizeRemaining;
            }
    
            return dividedArrays;
        }

0
投票

我知道这是一个非常老的问题,但我会将数据加载到表变量中,然后使用联接。

类似:

declare @t as table (ID int primary key)

insert into @t
'however you want to do this'

update mt
    set mycol = null
from MyTable mt
    join @t t on t.ID=mt.ID
© www.soinside.com 2019 - 2024. All rights reserved.