【发布时间】:2014-02-06 20:24:51
【问题描述】:
我已经阅读了很多查询优化,并且我已经能够优化其中的大部分。
不过,我有一个非常复杂的查询。它为我的会计账户创造了累积价值。该查询运行时间超过 10 分钟,我认为它应该是一种更好的优化方法,但我没有弄清楚。
我要优化的代码是这样的:
SELECT Empresa, IDCuenta, Año, Periodo, Saldo,
((SELECT SUM(Saldo)
FROM
(SELECT Empresa, IDCuenta, ReferenciaOrden, SUM(Saldo) As Saldo
FROM
(SELECT Empresa, IDCuenta, ReferenciaOrden, SUM(Saldo) As Saldo
FROM dbo.GP_ContabilidadTrxActivas
WHERE FechaTransacción<=GETDATE()
GROUP BY Empresa, IDCuenta, ReferenciaOrden
UNION ALL
SELECT Empresa, IDCuenta, ReferenciaOrden, SUM(Saldo) As Saldo
FROM dbo.GP_ContabilidadTrxHistoricas
WHERE FechaTransacción<=GETDATE()
GROUP BY Empresa, IDCuenta, ReferenciaOrden
) As Base
GROUP BY Empresa, IDCuenta, ReferenciaOrden) As BaseInt
WHERE BaseInt.IDCuenta=BaseTotal.IDCuenta AND BaseInt.Empresa = BaseTotal.Empresa
AND BaseInt.ReferenciaOrden<=BaseTotal.ReferenciaOrden
)) As SaldoAcumulado
FROM
(SELECT Empresa, IDCuenta, Año, Periodo, ReferenciaOrden, SUM(Saldo) As Saldo
FROM
(SELECT Empresa, IDCuenta, Año, Periodo, ReferenciaOrden, SUM(Saldo) As Saldo
FROM dbo.GP_ContabilidadTrxActivas WITH (INDEX(IX_ReferenciaOrden)
WHERE FechaTransacción<=GETDATE()
GROUP BY Empresa, IDCuenta, Año, Periodo,ReferenciaOrden
UNION ALL
SELECT Empresa, IDCuenta, Año, Periodo, ReferenciaOrden, SUM(Saldo) As Saldo
FROM dbo.GP_ContabilidadTrxHistoricas WITH (INDEX(IX_ReferenciaOrden)
WHERE FechaTransacción<=GETDATE()
GROUP BY Empresa, IDCuenta, Año, Periodo,ReferenciaOrden
) As Base
GROUP BY Empresa, IDCuenta, Año, Periodo, ReferenciaOrden) As BaseTotal
我为此查询创建的索引是:
CREATE NONCLUSTERED INDEX IX_ReferenciaOrden
ON dbo.GP_ContabilidadTrxHistoricas (IDCuenta ASC, ReferenciaOrden ASC)
INCLUDE (Empresa, Año, Periodo, Saldo, FechaTransacción);
CREATE NONCLUSTERED INDEX IX_ReferenciaOrden
ON dbo.GP_ContabilidadTrxActivas (IDCuenta ASC, ReferenciaOrden ASC)
INCLUDE (Empresa, Año, Periodo, Saldo, FechaTransacción);
执行计划显示 87% 的成本在 3 个活动中:Index Seek、Stream Aggregate 和 Merge Join,这是部分估计执行计划的图像:
dbo.GP_ContabilidadTrxHistoricas 有 3.559.617 行,dbo.GP_ContabilidadTrxActivas 有 102.707 行
任何优化它的建议都将受到欢迎。提前致谢。
【问题讨论】:
-
您是否也尝试过不使用索引 HINTS?这是否给出了相同的执行计划?也许在 cte 中获取 UNION ALL 查询并在之后使用它?您似乎使用了两次该查询,对吗?
-
您在查询提示后丢失了 )。
-
@SaUce 查询运行正常,我只是错过了在这里输入的问题。
-
@NickyvV 是的,我使用了两次,因为我需要做累计金额。我在没有索引 HINTS 的情况下做到了,但给了我一个更昂贵的执行计划。我会尝试 CTE 来检查是否效果更好。谢谢!
标签: sql sql-server optimization sql-server-2008-r2