I have been reading a lot of Query Optimizations and I have been capable of optimizing most of them.
Nevertheless, I have a very complex query. It creates accumulated values for my accounting accounts. The query is taking more than 10 minutes to run, and I think that it should be a better way to optimize it, but I am not figuring out it.
The code that I want to optimize is this:
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
The indexes that I created for this query are:
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);
The execution plans shows that 87% of the cost are in 3 activities: Index Seek, Stream Aggregate and Merge Join, this is the image of the partial estimated execution plan:
dbo.GP_ContabilidadTrxHistoricas has 3.559.617 rows and dbo.GP_ContabilidadTrxActivas has 102.707 rows
Any advise to optimize it would be more than welcome. Thanks in advance.