我们正在尝试设置一个游标来运行从同一个巨大表的两个“实例”之间的连接生成的记录(超过 150 M 记录)。
出现以下异常消息:
无法为数据库“tempdb”中的对象“dbo.SORT 临时运行存储:165282123350016”分配空间,因为“PRIMARY”文件组已满。通过删除不需要的文件、删除文件组中的对象、向文件组添加其他文件或为文件组中的现有文件设置自动增长来创建磁盘空间。
你们有谁知道这其中的原因吗?或者如何使下面的查询更有效率?
我发现它发生在DECLARE CURSOR
和第一个之间的某个地方FETCH NEXT
,但我还不知道它是否介于...
DECLARE CURSOR
和OPEN
或之间
OPEN
和第一个FETCH NEXT
。
更多细节: sql 语句如下所示:
DECLARE cData CURSOR LOCAL FORWARD_ONLY READ_ONLY 为了 选择 ... 从 HugeTable HT1 加入 HugeTable HT2 .. 加入表 3 开 .. 加入表 4 开 .. 加入表 5 开 .. 在哪里 ... 由 HT1 订购..., HT1... 插入系统日志(描述)值('A') 打开 cData 开始交易流程数据 -- 目前在这里尝试新的日志记录: -- 插入系统日志(描述)值('B') FETCH NEXT FROM cData INTO ... 插入到系统日志(描述)值('C') ... ETC。
我收到的最后一条日志消息是“A”,然后一小时后它失败并显示上述消息,从未达到“C”。我现在正在尝试在“B”点记录。
根据要求,我发布了确切的 sql 表达式:
DECLARE cSource CURSOR LOCAL FORWARD_ONLY READ_ONLY 为了 选择 MD.s 字段名称, MD.sFieldValue, TR.sTargetDataType, MD2.sFieldValue AS sUniqueID, TR.sTargetTableName, TR.sTargetFieldName, I.iRefCustomerID, I.iInterfaceID, IL.iRefInterfaceSessionID 来自 MasterData MD 加入 MasterData MD2 ON MD.iRowIndex = MD2.iRowIndex AND MD.iBatchNumber = MD2.iBatchNumber AND MD.sTableName = MD2.sTableName AND MD2.sFieldName = 'sUniqueID' 加入 SourceTargetRelation TR ON MD.sFieldName = TR.sSourceFieldName AND MD.sTableName = TR.sSourceTableName JOIN 接口Log IL ON IL.iInterfaceLogID = MD.iBatchNumber JOIN接口一 ON I.iInterfaceID = IL.iRefInterfaceID AND TR.iRefSystemID = I.iRefSystemID 在哪里 MD.iBatchNumber = @iBatchNumber 按 MD.sTableName、MD.iRowIndex 排序
在 Quassnoi 更新答案后,我还将原始索引发布在桌子上:
我在此表上有一个非聚集索引,其中包含iBatchNumber
、sFieldName
、sTableName
、列iRowIndex
。该索引sFieldValue
作为包含列。
正如 Quassnoi 建议的那样(我想我现在明白为什么了)我已经更改了索引以使列按以下顺序排列:iBatchNumber
, sTableName
, iRowIndex
, sFieldName
。我sFieldValue
用作包含的列。执行计划不再包含任何内容SORT
,并且执行计划中的步骤数不到原来的一半,我希望这也更快......