September 6, 2012 at 8:54 am
Hi,
I have a customer database that has a view with the following definition:
CREATE VIEW [dbo].[V_Documentos]
AS
SELECT Movimentos.Id, Movimentos.Conta, Movimentos.ValorAlt, Movimentos.Dia, Movimentos.Diario, Movimentos.NumDiario, Movimentos.Documento,
Movimentos.NumDoc, Movimentos.ContaOrigem, Movimentos.Descricao AS DescMov, Movimentos.Valor, Movimentos.Natureza, Movimentos.Iva,
Movimentos.Selo, Movimentos.TipoConta, Movimentos.Entidade, Movimentos.Moeda, Movimentos.ClassOrgan, Movimentos.ContaOrc,
Movimentos.Ano, PlanoContas.Descricao AS DescConta, Diarios.Descricao AS DescDiario, DocumentosCBL.Descricao AS DescDoc,
Movimentos.Cambio, Movimentos.CambioOrigem, Movimentos.ValorOrigem, Movimentos.TipoAfectacao, Movimentos.CambioMAlt, Movimentos.Linha,
Movimentos.Mes, Movimentos.IdCabec, Movimentos.PercNdedutivel, Movimentos.IvaAutoLiquidacao, Movimentos.TipoLancamento, TiposLancamento.Descricao AS DescTipoLancamento
FROM dbo.Movimentos AS Movimentos INNER JOIN
dbo.PlanoContas AS PlanoContas ON Movimentos.Ano = PlanoContas.Ano AND Movimentos.Conta = PlanoContas.Conta INNER JOIN
dbo.Diarios AS Diarios ON Movimentos.Diario = Diarios.Diario LEFT OUTER JOIN
dbo.DocumentosCBL AS DocumentosCBL ON Movimentos.Documento = DocumentosCBL.Documento
INNER JOIN dbo.TiposLancamento AS TiposLancamento ON Movimentos.TipoLancamento = TiposLancamento.TipoLancamento
WHERE (Movimentos.TipoConta <> 'O') AND (Movimentos.TipoConta <> 'C')
UNION
SELECT Movimentos.Id, Movimentos.Conta, Movimentos.ValorAlt, Movimentos.Dia, Movimentos.Diario, Movimentos.NumDiario, Movimentos.Documento,
Movimentos.NumDoc, Movimentos.ContaOrigem, Movimentos.Descricao AS DescMov, Movimentos.Valor, Movimentos.Natureza, Movimentos.Iva,
Movimentos.Selo, Movimentos.TipoConta, Movimentos.Entidade, Movimentos.Moeda, Movimentos.ClassOrgan, Movimentos.ContaOrc,
Movimentos.Ano, PlanoCentros.Descricao AS DescConta, Diarios.Descricao AS DescDiario, DocumentosCBL.Descricao AS DescDoc,
Movimentos.Cambio, Movimentos.CambioOrigem, Movimentos.ValorOrigem, Movimentos.TipoAfectacao, Movimentos.CambioMAlt, Movimentos.Linha,
Movimentos.Mes, Movimentos.IdCabec, Movimentos.PercNdedutivel, Movimentos.IvaAutoLiquidacao, Movimentos.TipoLancamento, TiposLancamento.Descricao AS DescTipoLancamento
FROM dbo.Movimentos AS Movimentos INNER JOIN
dbo.PlanoCentros AS PlanoCentros ON Movimentos.Ano = PlanoCentros.Ano AND Movimentos.Conta = PlanoCentros.Centro INNER JOIN
dbo.Diarios AS Diarios ON Movimentos.Diario = Diarios.Diario LEFT OUTER JOIN
dbo.DocumentosCBL AS DocumentosCBL ON Movimentos.Documento = DocumentosCBL.Documento
INNER JOIN dbo.TiposLancamento AS TiposLancamento ON Movimentos.TipoLancamento = TiposLancamento.TipoLancamento
WHERE (Movimentos.TipoConta = 'O')
UNION
SELECT Movimentos.Id, Movimentos.Conta, Movimentos.ValorAlt, Movimentos.Dia, Movimentos.Diario, Movimentos.NumDiario, Movimentos.Documento,
Movimentos.NumDoc, Movimentos.ContaOrigem, Movimentos.Descricao AS DescMov, Movimentos.Valor, Movimentos.Natureza, Movimentos.Iva,
Movimentos.Selo, Movimentos.TipoConta, Movimentos.Entidade, Movimentos.Moeda, Movimentos.ClassOrgan, Movimentos.ContaOrc,
Movimentos.Ano, PlanoFuncional.Descricao AS DescConta, Diarios.Descricao AS DescDiario, DocumentosCBL.Descricao AS DescDoc,
Movimentos.Cambio, Movimentos.CambioOrigem, Movimentos.ValorOrigem, Movimentos.TipoAfectacao, Movimentos.CambioMAlt, Movimentos.Linha,
Movimentos.Mes, Movimentos.IdCabec, Movimentos.PercNdedutivel, Movimentos.IvaAutoLiquidacao, Movimentos.TipoLancamento, TiposLancamento.Descricao AS DescTipoLancamento
FROM dbo.Movimentos AS Movimentos INNER JOIN
dbo.PlanoFuncional AS PlanoFuncional ON Movimentos.Ano = PlanoFuncional.Ano AND Movimentos.Conta = PlanoFuncional.Funcao INNER JOIN
dbo.Diarios AS Diarios ON Movimentos.Diario = Diarios.Diario LEFT OUTER JOIN
dbo.DocumentosCBL AS DocumentosCBL ON Movimentos.Documento = DocumentosCBL.Documento
INNER JOIN dbo.TiposLancamento AS TiposLancamento ON Movimentos.TipoLancamento = TiposLancamento.TipoLancamento
WHERE (Movimentos.TipoConta = 'C')
Isn't this the same as having:
SELECT Movimentos.Id, Movimentos.Conta, Movimentos.ValorAlt, Movimentos.Dia, Movimentos.Diario, Movimentos.NumDiario, Movimentos.Documento,
Movimentos.NumDoc, Movimentos.ContaOrigem, Movimentos.Descricao AS DescMov, Movimentos.Valor, Movimentos.Natureza, Movimentos.Iva,
Movimentos.Selo, Movimentos.TipoConta, Movimentos.Entidade, Movimentos.Moeda, Movimentos.ClassOrgan, Movimentos.ContaOrc,
Movimentos.Ano, PlanoContas.Descricao AS DescConta, Diarios.Descricao AS DescDiario, DocumentosCBL.Descricao AS DescDoc,
Movimentos.Cambio, Movimentos.CambioOrigem, Movimentos.ValorOrigem, Movimentos.TipoAfectacao, Movimentos.CambioMAlt, Movimentos.Linha,
Movimentos.Mes, Movimentos.IdCabec, Movimentos.PercNdedutivel, Movimentos.IvaAutoLiquidacao, Movimentos.TipoLancamento, TiposLancamento.Descricao AS DescTipoLancamento
FROM dbo.Movimentos AS Movimentos
LEFT JOIN dbo.PlanoContas AS PlanoContas ON Movimentos.Ano = PlanoContas.Ano AND Movimentos.Conta = PlanoContas.Conta
LEFT JOIN dbo.PlanoCentros AS PlanoCentros ON Movimentos.Ano = PlanoCentros.Ano AND Movimentos.Conta = PlanoCentros.Centro
LEFT JOIN dbo.PlanoFuncional AS PlanoFuncional ON Movimentos.Ano = PlanoFuncional.Ano AND Movimentos.Conta = PlanoFuncional.Funcao
INNER JOIN dbo.Diarios AS Diarios ON Movimentos.Diario = Diarios.Diario
LEFT JOIN dbo.DocumentosCBL AS DocumentosCBL ON Movimentos.Documento = DocumentosCBL.Documento
INNER JOIN dbo.TiposLancamento AS TiposLancamento ON Movimentos.TipoLancamento = TiposLancamento.TipoLancamento
WHERE
(Movimentos.TipoConta <> 'O' AND Movimentos.TipoConta <> 'C' AND PlanoContas.Ano IS NOT NULL)
OR (Movimentos.TipoConta = 'O' AND PlanoCentros.Ano IS NOT NULL)
OR (Movimentos.TipoConta = 'C' AND PlanoFuncional.Ano IS NOT NULL)
The result is the same on both queries. The Execution plan gives 50% for each query... this means that both queries have the same "weight".... How can this be?!
I then turn the statistics IO on and got this data:
For the view with the UNION:
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'PlanoContas'. Scan count 1, logical reads 142, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Movimentos'. Scan count 5, logical reads 66, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TiposLancamento'. Scan count 3, logical reads 6, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Diarios'. Scan count 1, logical reads 14, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'PlanoCentros'. Scan count 0, logical reads 6, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'PlanoFuncional'. Scan count 0, logical reads 6, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'DocumentosCBL'. Scan count 1, logical reads 15, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
For the other query, with the LEFT JOINs:
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'PlanoContas'. Scan count 1, logical reads 142, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Movimentos'. Scan count 1, logical reads 46, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'TiposLancamento'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Diarios'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'PlanoCentros'. Scan count 1, logical reads 2, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'PlanoFuncional'. Scan count 1, logical reads 4, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'DocumentosCBL'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
The 2nd query has less logical reads... This is better right?!
Thanks,
Pedro
September 6, 2012 at 9:24 am
That's not exactly the same result.
This might do it, but I can't test it:
SELECT Movimentos.Id,
Movimentos.Conta,
Movimentos.ValorAlt,
Movimentos.Dia,
Movimentos.Diario,
Movimentos.NumDiario,
Movimentos.Documento,
Movimentos.NumDoc,
Movimentos.ContaOrigem,
Movimentos.Descricao AS DescMov,
Movimentos.Valor,
Movimentos.Natureza,
Movimentos.Iva,
Movimentos.Selo,
Movimentos.TipoConta,
Movimentos.Entidade,
Movimentos.Moeda,
Movimentos.ClassOrgan,
Movimentos.ContaOrc,
Movimentos.Ano,
--Change in here
COALESCE( PlanoContas.Descricao, PlanoCentros.Descricao, PlanoFuncional.Descricao) AS DescConta,
Diarios.Descricao AS DescDiario,
DocumentosCBL.Descricao AS DescDoc,
Movimentos.Cambio,
Movimentos.CambioOrigem,
Movimentos.ValorOrigem,
Movimentos.TipoAfectacao,
Movimentos.CambioMAlt,
Movimentos.Linha,
Movimentos.Mes,
Movimentos.IdCabec,
Movimentos.PercNdedutivel,
Movimentos.IvaAutoLiquidacao,
Movimentos.TipoLancamento,
TiposLancamento.Descricao AS DescTipoLancamento
FROM dbo.Movimentos AS Movimentos
LEFT JOIN dbo.PlanoContas AS PlanoContas ON Movimentos.Ano = PlanoContas.Ano
AND Movimentos.Conta = PlanoContas.Conta
AND Movimentos.TipoConta <> 'O' --Moved this from the WHERE clause
AND Movimentos.TipoConta <> 'C' --Moved this from the WHERE clause
LEFT JOIN dbo.PlanoCentros AS PlanoCentros ON Movimentos.Ano = PlanoCentros.Ano
AND Movimentos.Conta = PlanoCentros.Centro
AND Movimentos.TipoConta = 'O' --Moved this from the WHERE clause
LEFT JOIN dbo.PlanoFuncional AS PlanoFuncional ON Movimentos.Ano = PlanoFuncional.Ano
AND Movimentos.Conta = PlanoFuncional.Funcao
AND Movimentos.TipoConta = 'C' --Moved this from the WHERE clause
INNER JOIN dbo.Diarios AS Diarios ON Movimentos.Diario = Diarios.Diario
LEFT JOIN dbo.DocumentosCBL AS DocumentosCBL ON Movimentos.Documento = DocumentosCBL.Documento
INNER JOIN dbo.TiposLancamento AS TiposLancamento ON Movimentos.TipoLancamento = TiposLancamento.TipoLancamento
Check where I did the changes and you'll have to evaluate which one will perform better. It depends on multiple things and you didn't provide enough information to check it.
September 6, 2012 at 9:42 am
Missed that column 🙂 Thanks.
Now the execution plan is even weirder, since it says the UNION query is faster, but looking at the IO statistics that query has more logical reads than the LEFT JOIN one...
Viewing 3 posts - 1 through 3 (of 3 total)
You must be logged in to reply to this topic. Login to reply