【问题标题】:Could not allocate space for object '<temporary system object: 422212632707072>' in database 'tempdb' because the 'PRIMARY' filegroup is full无法为数据库“tempdb”中的对象“<临时系统对象:422212632707072>”分配空间,因为“PRIMARY”文件组已满
【发布时间】:2015-12-29 16:48:56
【问题描述】:

我正在尝试执行此语句,但出现此错误:

无法为数据库“tempdb”中的对象“”分配空间,因为“PRIMARY”文件组已满。通过删除不需要的文件、删除文件组中的对象、向文件组中添加其他文件或为文件组中的现有文件设置自动增长来创建磁盘空间。

SQL语句:

DECLARE
@curvaTipicaPeriodoMes VARCHAR(50),
@curvaTipicaPeriodoAnio VARCHAR(50),
@curvaTipicaTipo VARCHAR(50),
@curvaTipicaTipoInicial VARCHAR(50),
@fronteraEstado VARCHAR(50),
@fronteraFechaFin DATETIME,
@birrelacion VARCHAR(50),
@birrelacionTipo VARCHAR(50)

SET @curvaTipicaPeriodoMes='10'
SET @curvaTipicaPeriodoAnio= '2014'
SET @curvaTipicaTipo='ValorTipico'
SET @curvaTipicaTipoInicial='ValorTipicoInicial'
SET @fronteraEstado='Operacion'
SET @fronteraFechaFin = NULL
SET @birrelacion='Bir0111'
SET @birrelacionTipo='Tfr0005'

SELECT
    Consulta.tipoDia,
    CASE WHEN Consulta.ValorTipico > 0 THEN Consulta.ValorTipico ELSE Consulta.ValorTipicoInicial END AS Calculo
FROM
   (SELECT 
        C.tipoDia,
        (SELECT (ISNULL(SUM(CC.periodo01),0) + ISNULL(SUM(CC.periodo02),0) + ISNULL(SUM(CC.periodo03),0) + ISNULL(SUM(CC.periodo04),0) + ISNULL(SUM(CC.periodo05),0) + ISNULL(SUM(CC.periodo06),0) + ISNULL(SUM(CC.periodo07),0) + ISNULL(SUM(CC.periodo08),0) + ISNULL(SUM(CC.periodo09),0) +  ISNULL(SUM(CC.periodo10),0) + ISNULL(SUM(CC.periodo11),0) + ISNULL(SUM(CC.periodo12),0) + ISNULL(SUM(CC.periodo13),0) + ISNULL(SUM(CC.periodo14),0) + ISNULL(SUM(CC.periodo15),0) + ISNULL(SUM(CC.periodo16),0) + ISNULL(SUM(CC.periodo17),0) + ISNULL(SUM(CC.periodo18),0) + ISNULL(SUM(CC.periodo19),0) + ISNULL(SUM(CC.periodo20),0) + ISNULL(SUM(CC.periodo21),0) + ISNULL(SUM(CC.periodo22),0) + ISNULL(SUM(CC.periodo23),0) + ISNULL(SUM(CC.periodo24),0)
)
FROM 
[registrar].[CurvaTipica] CC 
WHERE
CC.tipo = @curvaTipicaTipo 
AND CC.tipoDia=C.tipoDia
AND
DATEPART(MONTH,CC.periodo) = @curvaTipicaPeriodoMes 
AND DATEPART(YEAR,CC.periodo) = @curvaTipicaPeriodoAnio 
) * COUNT(C.tipoDia)
AS ValorTipico,
(
SELECT 
(
ISNULL(SUM(CC.periodo01),0) + ISNULL(SUM(CC.periodo02),0) + ISNULL(SUM(CC.periodo03),0) + ISNULL(SUM(CC.periodo04),0) + 
ISNULL(SUM(CC.periodo05),0) + ISNULL(SUM(CC.periodo06),0) + ISNULL(SUM(CC.periodo07),0) + ISNULL(SUM(CC.periodo08),0) +
ISNULL(SUM(CC.periodo09),0) + ISNULL(SUM(CC.periodo10),0) + ISNULL(SUM(CC.periodo11),0) + ISNULL(SUM(CC.periodo12),0) + 
ISNULL(SUM(CC.periodo13),0) + ISNULL(SUM(CC.periodo14),0) + ISNULL(SUM(CC.periodo15),0) + ISNULL(SUM(CC.periodo16),0) +
ISNULL(SUM(CC.periodo17),0) + ISNULL(SUM(CC.periodo18),0) + ISNULL(SUM(CC.periodo19),0) + ISNULL(SUM(CC.periodo20),0) + 
ISNULL(SUM(CC.periodo21),0) + ISNULL(SUM(CC.periodo22),0) + ISNULL(SUM(CC.periodo23),0) + ISNULL(SUM(CC.periodo24),0)
)
FROM 
[registrar].[CurvaTipica] CC 
WHERE
CC.tipo = @curvaTipicaTipoInicial
AND CC.tipoDia=C.tipoDia
AND
DATEPART(MONTH,CC.periodo) = @curvaTipicaPeriodoMes 
AND DATEPART(YEAR,CC.periodo) = @curvaTipicaPeriodoAnio 
) * COUNT(C.tipoDia)
AS ValorTipicoInicial
FROM [registrar].[CurvaTipica] C 
INNER JOIN [dbo].[Frontera] F ON c.frtID=F.objID 
INNER JOIN [dbo].[Birrelacion] B ON B.objID1=C.frtID
WHERE
DATEPART(MONTH,C.periodo) = @curvaTipicaPeriodoMes 
AND
DATEPART(YEAR,C.periodo) = @curvaTipicaPeriodoAnio 
AND
F.estado = @fronteraEstado 
AND
F.fechaFin IS NULL 
AND
B.objID = @birrelacion 
AND
B.objID2 = @birrelacionTipo
GROUP BY 
C.tipoDia
) Consulta
ORDER BY
Calculo

我检查了一下,tempdb 的大小为 1400mb,自动增长为 10%。

【问题讨论】:

  • SQL Server 的哪个版本?老实说,这对 DBA 来说可能会更好。虽然我不确定我是否希望看到它以当前状态迁移。这不是一个很好的问题。
  • 磁盘满了吗?你对增长有限制吗?
  • 数据库文件所在的驱动器上的可用磁盘空间如何?
  • 另外,为什么您的查询使用了 1.4 GB 的临时空间?这感觉是个坏主意。
  • 我刚刚注意到内部选择,返回1000万行,即使选择计数也需要45秒

标签: sql-server tsql


【解决方案1】:

我很难理解此查询的上下文,这使我无法在此处提供我认为是答案的全部潜力。特别是,当您按 TipoDia 分组时,为什么您的总和乘以 TipoDia 的计数,我对此感到困惑。

简而言之,我发现有几件事会导致大量且不受欢迎的日志增长:

  • 您处理日期限制的方式:您基本上需要在整个表上运行该日期部分,然后才能进行过滤。将其更改为表中列上没有函数的 BETWEEN。
  • 非常不寻常的嵌套:我无法理解它,但我怀疑这会导致大量临时空间使用。我在下面放了一些示例代码,说明您如何摆脱这种情况,但我意识到它与您的原始陈述不匹配。它应该能够为您指明正确的方向。如果不出意外,请将您的查询分解为三个或四个较小的临时表,然后将它们重新组合在一起,而不是尝试将所有内容放在一个包含那么多连接的庞大语句中。
  • NULLIF:这实际上又与嵌套有关,但我怀疑 NULLIF 运行在您为表的每一行列出的每一列上。摆脱嵌套语句以解决此问题,或者在嵌套部分之外进行添加。

    DECLARE
        @curvaTipicaPeriodoBegin datetime,
        @curvaTipicaPeriodoEnd datetime,
        @curvaTipicaTipo VARCHAR(50),
        @curvaTipicaTipoInicial VARCHAR(50),
        @fronteraEstado VARCHAR(50),
        @birrelacion VARCHAR(50),
        @birrelacionTipo VARCHAR(50);
    
    SET     @curvaTipicaPeriodoBegin = '2014-10-01';
    SET     @curvaTipicaPeriodoEnd = '2014-10-31';
    SET     @curvaTipicaTipo='ValorTipico';
    SET     @curvaTipicaTipoInicial='ValorTipicoInicial';
    SET     @fronteraEstado='Operacion';
    SET     @birrelacion='Bir0111';
    SET     @birrelacionTipo='Tfr0005';
    
    SELECT
        CurvaTipica.tipoDia,
        CurvaTipica.tipo,
        SUM
            (
            ISNULL(CurvaTipica.periodo01,0) + ISNULL(CurvaTipica.periodo02,0) + ISNULL(CurvaTipica.periodo03,0) + ISNULL(CurvaTipica.periodo04,0) + 
            ISNULL(CurvaTipica.periodo05,0) + ISNULL(CurvaTipica.periodo06,0) + ISNULL(CurvaTipica.periodo07,0) + ISNULL(CurvaTipica.periodo08,0) +
            ISNULL(CurvaTipica.periodo09,0) + ISNULL(CurvaTipica.periodo10,0) + ISNULL(CurvaTipica.periodo11,0) + ISNULL(CurvaTipica.periodo12,0) + 
            ISNULL(CurvaTipica.periodo13,0) + ISNULL(CurvaTipica.periodo14,0) + ISNULL(CurvaTipica.periodo15,0) + ISNULL(CurvaTipica.periodo16,0) +
            ISNULL(CurvaTipica.periodo17,0) + ISNULL(CurvaTipica.periodo18,0) + ISNULL(CurvaTipica.periodo19,0) + ISNULL(CurvaTipica.periodo20,0) + 
            ISNULL(CurvaTipica.periodo21,0) + ISNULL(CurvaTipica.periodo22,0) + ISNULL(CurvaTipica.periodo23,0) + ISNULL(CurvaTipica.periodo24,0)
            ) ValorTipico
    FROM
        registrar.CurvaTipica
        JOIN 
        Frontera
        ON
            CurvaTipica.frtID = Frontera.objID
        JOIN
        Birrelacion
        ON
            CurvaTipica.frtID = Birrelacion.objID1
    WHERE
        CurvaTipica.periodo BETWEEN @curvaTipicaPeriodoBegin AND @curvaTipicaPeriodoEnd
        AND
        Frontera.estado = @fronteraEstado 
        AND
        Frontera.fechaFin IS NULL 
        AND
        Birrelacion.objID = @birrelacion
        AND
        Birrelacion.objID2 = @birrelacionTipo
        AND
        (
        CurvaTipica.tipo = @curvaTipicaTipo
        OR
        CurvaTipica.tipo = @curvaTipicaTipoInicial
        )
    GROUP BY
        CurvaTipica.tipoDia,
        CurvaTipica.tipo;
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-17
    • 2023-01-12
    相关资源
    最近更新 更多