1

我有一个查询,它检索大约 184K 行并存储到临时表中。现在,在第二个查询中,我首先从临时表中检索所有数据并将其旋转。旋转时,我遇到了错误。

消息 1105,级别 17,状态 2,第 56 行无法为数据库“tempdb”中的对象“dbo.WORKFILE GROUP 大型记录溢出存储:140761897762816”分配空间,因为“PRIMARY”文件组已满。通过删除不需要的文件、删除文件组中的对象、向文件组添加其他文件或为文件组中的现有文件设置自动增长来创建磁盘空间。

SQL查询如下:

        SELECT *
        FROM
        (
            SELECT Id,
                   Name,
                   ROW_NUMBER() OVER (PARTITION BY Id,
                                                   Name
                                      ORDER BY
                                          (
                                              SELECT NULL
                                          )
                                     ) AS [Row Number],
                   [Value]
            FROM #Data --184K Rows
        ) AS S
        PIVOT
        (
            MAX([Value])
            FOR Name IN ([A],[B],[C],[D],[E],[F],[G],[H],[I],[J],[K],[L],[M],[N],[O],[P],[Q],[R]
                                   )
        ) AS PVT;

在此处输入图像描述

我们可以在不增加 tempDB 大小的情况下解决这个问题吗?

4

1 回答 1

0

(猜测,因为您没有发布 sql 或计划)如果您使用 PIVOT,它通常会以聚合结束,并且可能是 streamagg。这可以有一个排序(将转到 tempdb)。这本身不太可能耗尽空间。但是,我们看到的另一种模式是对每个属性执行子选择 SELECT (SELECT MAX(col1) FROM T WHERE col='value', ...) FROM ...。这可能会导致可以通过排序实现的聚合每个属性。因此,如果您最终尝试旋转一个非常大的表,这可能是您查询临时空间不足的原因。请考虑您用于编写查询的模式。如果您的查询计划中包含许多假脱机/排序,您可能可以迁移到 PIVOT 并减少所需的排序数量。

于 2018-07-25T16:47:48.167 回答