【发布时间】:2021-05-14 13:19:45
【问题描述】:
对本地数据库运行查询时出现以下错误:
查询处理器无法生成查询计划,因为需要工作表,并且其最小行大小超过了允许的最大 8060 字节。需要工作表的一个典型原因是查询中的 GROUP BY 或 ORDER BY 子句。如果查询有 GROUP BY 或 ORDER BY 子句,请考虑减少子句中字段的数量和/或大小。考虑使用字段的前缀 (LEFT()) 或哈希 (CHECKSUM()) 进行分组或使用前缀进行排序。但是请注意,这会改变查询的行为。
在运行与此类似的查询时会发生这种情况(为缺乏细节道歉):
SELECT <about 183 columns>
FROM tableA
INNER JOIN tvf1(<params>) tvf1
ON tvf1.id = tableA.X1
INNER JOIN tvf2(<params>) tvf2
ON tvf2.id = tableA.X2
INNER JOIN tvf3(<params>) tvf3
ON tvf3.id = tableA.X3
INNER JOIN tvf4(<params>) tvf4
ON tvf4.id = tableA.X4
INNER JOIN tvf5(<params>) tvf5
ON tvf5.id = tableA.X5
上面的表值函数都使用了GROUP BY、ROW_NUMBER()和其他聚合函数的组合。
在二进制调试时,注释掉上述任何两个连接都会导致错误不会发生,但不管怎样。
我的数据库在Compatibility Level 2019 上运行。
如果我尝试将Legacy Cardinality Estimation 设置为On,则错误不再发生,但我不明白此设置的作用。
编辑:
如果数据库兼容级别为2016,那么一切都按预期工作
我担心的是生产数据库将来可能会升级,并且可能会发生此错误。
编辑: 我现在已经设法将列数减少到少数,但是我的结果不一致。
SELECT
Other = TvfGroupData.Other
,GroupA = TvfGroupData.GroupA
,GroupB = TvfGroupData.GroupB
,GroupC = TvfGroupData.GroupC
, [Max Created Date] =
(SELECT MAX(Value)
FROM (VALUES
(Tvf1.CreatedDate)
,(Tvf2.CreatedDate)
,(Tvf3.CreatedDate)
--,(TvfGroupData.CreatedDate)
,(Tvf3.CreatedDate)
,(Tvf4.CreatedDate)
) AS AllValues(Value)
)
FROM TableA
LEFT JOIN Tvf1() ...
LEFT JOIN Tvf2() ...
LEFT JOIN TvfGroupData() ...
LEFT JOIN Tvf3() ...
LEFT JOIN Tvf4() ...
在上述查询中,以下场景有效:
- 仅排除 GroupA 列。
- 仅排除 GroupB、GroupC 列
其他组合都失败并出现错误:
查询处理器用尽了内部资源,无法生成查询计划。这是一个罕见的事件,仅适用于极其复杂的查询或引用大量表或分区的查询。请简化查询。如果您认为自己错误地收到了此消息,请联系客户支持服务以获取更多信息。
【问题讨论】:
-
你对所有这些列做了什么?
-
这是一个最终用户报告。大量统计数据等
-
在使用数据库 20 年的时间里,我从来没有在一次查询中需要接近 180 多列。您是否使用了很多 (n) varchar 大小延迟的列?
-
表中有数据类型及其列数: bigint(5) date(2) datetime2(4) decimal(73) int(41) nvarchar(57) varchar( 1)
-
我建议您的结果集中不太可能需要 183 列;特别是当数据引擎有效地告诉您行太“宽”时。我也希望你的 TVF 是内联函数,而不是多行函数,
标签: sql-server