透视1300万条记录时,tempDB已在SQL Server中充满,并且透视花费了28个小时以上

时间:2018-12-07 04:48:15

标签: sql sql-server tsql pivot

我有一张表消耗1300万条记录(将来数据会增加),大约是2.5gb。此外,该表不是临时表。当我们尝试透视表时,SQL给出如下结果

  

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

此外,它花费的时间太长。 (超过28小时),此时该SQL Server上没有其他任务在运行。

我们在计算机中总共有16gb物理内存,其中16gb已分配给SQL Server 12gb。该机器有4个核心。对于文件类型ROWS数据,总共有4个文件组,对于日志,则有一个文件组,所有5个文件都位于单独的驱动器中,该驱动器的总大小为50gb。 tempdb的初始大小为14gb。所有数据文件的自动增长为100MB,最大大小为无限。

SQL查询如下:

SET nocount ON 

SELECT * 
INTO isheetnewdata1_4_27 
FROM 
    (SELECT 
         historyid, 
         requestentityid, 
         fieldname, 
         fieldvalue, 
         siteid, 
         isheetid 
     FROM   
         synk_isheet_1_int  
     WHERE  
         historyid = 6 
         AND group1id = 27 
         AND group2id = 4) AS A 
PIVOT 
    (MAX(fieldvalue) 
     FOR fieldname IN ([ID], [LastName], [FirstName], [Age], [externalId])
    ) AS pvt 
ORDER BY 
    historyid, requestentityid

Table structure of synk_isheet_1_int

请注意,字段名可以更多,我们必须加以调整。

我正在Microsoft Azure中使用SQL Server 2016。我主要担心的是,数据透视需要花费28个小时以上的时间,并且由于tempdb的大小已达到该驱动器的最大大小。

我不知道在这个阶段该做什么。我是否必须增加tempdb数据库文件所在驱动器的大小?并增加该计算机的物理内存并为SQL Server提供更多内存?

Query execution plan

Expected pivot look like

谢谢

1 个答案:

答案 0 :(得分:0)

首先:请不要发布数据图片。没人想输入。最好尝试提供一个独立示例来重现您的问题。

第二:即使该表是临时创建的:使用如此昂贵的查询也值得创建索引。

您可以使用条件聚合,而不是使用PIVOT。这个想法是,使用分组集,将您的目标集减少为一个实体行(无论是哪种形式),并将CASE WHEN与{{1} }设置数据透视列

MAX()

不知道您的表和数据是否被蒙住了双眼。但是我的魔幻水晶球告诉我,这可能会帮助...

一个简化的例子

这是1)展示原理,2)展示如何设置独立样本。

SELECT t.historyid
      ,t.requestentityid
      ,MAX(CASE WHEN fieldname='ID' THEN fieldvalue END) AS ID
      ,MAX(CASE WHEN fieldname='LastName' THEN fieldvalue END) AS LastName
      ,MAX(CASE WHEN fieldname='Age' THEN fieldvalue END) AS Age
      ,MAX(CASE WHEN fieldname='externalId' THEN fieldvalue END) AS externalId
FROM synk_isheet_1_int t
WHERE t.historyid = 6 
  AND t.group1id = 27 
  AND t.group2id = 4
GROUP BY t.historyid,t.requestentityid;