Hi!
Sorry for bad english, I'm from Brazil.
In microsoft.public.sqlserver.ce haven't found a way to improve performance
of this query. Thanks for any help or reply!
This used to take almost 6 min !!! With index on E.Produto now takes about 30 sec...
1,909 row table
Ipaq 1950 - Samsung 300 Mhz - 32 MB RAM - Windows Mobile 5.0 - SQL CE
2.0
PK (all multiple columns) - tables:
Lotes - pk(Empresa, Lote, Contagem, Produto)
Contagem - pk(Empresa, Lote, Contagem, Produto)
Produtos - pk(Codigo) // this field also is FK <=> Produto in all other
tables
Estoque - pk(Empresa, Ordem, Produto)
Part of my VB.NET code with SQL:
sql_grd_inv = "SELECT L.Empresa, L.Lote, L.Contagem, L.Produto" _
& ", P.Unidade, P.Descr, P.Ref, P.Embgem, P.Marca" _
& ", Sum(CASE WHEN E.Estoque IS NULL THEN 0 ELSE E.Estoque END)" _
& "AS SomaEstoque, C.Qtde" _
& " FROM (" _
& "(Lotes L " _
& "LEFT JOIN Contagem C ON (L.Empresa = C.Empresa) " _
& "AND (L.Lote = C.Lote) AND (L.Contagem = C.Contagem) " _
& "AND (L.Produto = C.Produto)" _
& ") " _
& "LEFT JOIN Estoque E ON (L.Empresa = E.Empresa) " _
& "AND (L.Produto = E.Produto)" _
& ") " _
& "INNER JOIN Produtos P ON L.Produto = P.Codigo " _
& "GROUP BY L.Empresa, L.Lote, L.Contagem, L.Produto" _
& ", P.Unidade, P.Descr, P.Ref, P.Embgem, P.Marca, C.Qtde " _
& "HAVING (L.Empresa='" & IncEmpresa & "') " _
& "AND (L.Lote='" & Cbo_Lote_Pnl_Invent.Text & "') AND (L.Contagem='" _
& Cbo_Cont_Pnl_Invent.Text & "') " _
& "UNION " _
& "SELECT " _
& "C.Empresa, C.Lote, C.Contagem, C.Produto" _
& ", P.Unidade, P.Descr, P.Ref, P.Embgem, P.Marca" _
& ", Sum(CASE WHEN E.Estoque IS NULL THEN 0 ELSE E.Estoque END)" _
& "AS SomaEstoque, C.Qtde" _
& " FROM (" _
& "(Contagem C " _
& "LEFT JOIN Lotes L ON (C.Empresa = L.Empresa) " _
& "AND (C.Lote = L.Lote) AND (C.Contagem = L.Contagem) " _
& "AND (C.Produto = L.Produto)" _
& ") " _
& "LEFT JOIN Estoque E ON (C.Empresa = E.Empresa) " _
& "AND (C.Produto = E.Produto)" _
& ") " _
& "INNER JOIN Produtos P ON C.Produto = P.Codigo " _
& "GROUP BY C.Empresa, C.Lote, C.Contagem, C.Produto" _
& ", P.Unidade, P.Descr, P.Ref, P.Embgem, P.Marca, C.Qtde" _
& ", L.Empresa, L.Lote, L.Contagem, L.Produto " _
& "HAVING (L.Empresa Is Null) AND (L.Lote Is Null) " _
& "AND (L.Contagem Is Null) AND (L.Produto Is Null) " _
& "AND (C.Empresa='" & IncEmpresa & "') " _
& "AND (C.Lote='" & Cbo_Lote_Pnl_Invent.Text & "') AND (C.Contagem='" _
& Cbo_Cont_Pnl_Invent.Text & "') "
Did anyone have queries with more than one LEFT JOIN and 2,000 records?
I've composite PKs and indexes and I don't know if creating single indexes for each column (additionally or replacing the composite ones?) will improve this query. The query processor only use one index to run the query so I don't know wich one is being used.
I've detected that the first query (before the UNION) is the slowest. The second one most of the times returns no records and takes 1-2 seconds.
Here is a more clean version of the query:
SELECT
L.Empresa, L.Lote, L.Contagem, L.Produto,
P.Descr, Sum(CASE WHEN E.Estoque IS NULL THEN 0 ELSE E.Estoque END) AS SomaDeEstoque,
C.Qtde
FROM (
(Lotes L
LEFT JOIN Contagem C ON (L.Empresa = C.Empresa)
AND (L.Lote = C.Lote) AND (L.Contagem = C.Contagem)
AND (L.Produto = C.Produto)
)
LEFT JOIN Estoque E ON (L.Empresa = E.Empresa)
AND (L.Produto = E.Produto)
)
INNER JOIN Produtos P ON L.Produto = P.Codigo
GROUP BY L.Empresa, L.Lote, L.Contagem, L.Produto, P.Descr, C.Qtde
HAVING (L.Empresa='0001') AND (L.Lote='0001') AND (L.Contagem='1')
UNION
SELECT
C.Empresa, C.Lote, C.Contagem, C.Produto,
P.Descr, Sum(CASE WHEN E.Estoque IS NULL THEN 0 ELSE E.Estoque END) AS SomaDeEstoque,
C.Qtde
FROM (
(Contagem C
LEFT JOIN Lotes L ON (C.Produto = L.Produto)
AND (C.Contagem = L.Contagem) AND
(C.Empresa = L.Empresa) AND (C.Lote = L.Lote)
)
LEFT JOIN Estoque E ON (C.Produto = E.Produto)
AND (C.Empresa = E.Empresa)
)
INNER JOIN Produtos P ON C.Produto = P.Codigo
GROUP BY C.Empresa, C.Lote, C.Contagem, C.Produto, P.Descr, C.Qtde,
L.Empresa, L.Lote, L.Contagem, L.Produto
HAVING (L.Empresa Is Null) AND (L.Contagem Is Null) AND (L.Produto Is Null) AND (L.Lote Is Null)
AND (C.Empresa='0001') AND (C.Lote='0001') AND (C.Contagem='1')
No comments:
Post a Comment