2015-09-25 90 views
0

我有這個疑問:慢查詢

SELECT 
    Tbl_Clientes.strNome as Cliente, 
    Tbl_Clientes.strPostal as 'Código Postal', 
    Tbl_Clientes.strLocalidade as Cidade, 
    Mov_Venda_cab.dtmdata as 'Data Fatura', 
    Tbl_Clientes.strNumContrib as 'N. Contribuinte', 
    Mov_Venda_Lin.strCodArtigo as Artigo, 
    Tbl_Gce_CondicoesCompra.strCodArtigoFornecedor as 'Artigo Fornecedor', 
    Mov_Venda_Lin.strDescArtigo as 'Designação 1', 
    Mov_Venda_Lin.fltQuantidade*mov_venda_cab.intSinal as 'Qtd. Faturada', 
    Tbl_Gce_Artigos.strAbrevMedVnd as 'Unid. Venda', 
    mov_venda_lin.fltvalorliquido/Mov_Venda_Lin.fltQuantidade as 'Prç.Liq.', 
    mov_venda_lin.fltvalorliquido as 'Montante Liquido', 
    Tbl_Gce_Vendedores.strnome as Vendedor 
FROM 
    Mov_Venda_Lin 
INNER JOIN 
    Tbl_Gce_ArtigosFamilias ON Mov_Venda_Lin.strCodArtigo = Tbl_Gce_ArtigosFamilias.strCodArtigo 
INNER JOIN 
    Mov_Venda_Cab ON Mov_Venda_Cab.strCodSeccao = Mov_Venda_Lin.strCodSeccao 
        AND Mov_Venda_Cab.strAbrevTpDoc = Mov_Venda_Lin.strAbrevTpDoc 
        AND Mov_Venda_Cab.strCodExercicio = Mov_Venda_Lin.strCodExercicio 
        AND Mov_Venda_Cab.intNumero = Mov_Venda_Lin.INTNUMERO 
INNER JOIN 
    Tbl_Clientes ON Tbl_Clientes.intCodigo = Mov_Venda_Cab.intCodEntidade 
INNER JOIN 
    Tbl_Gce_CondicoesCompra ON Tbl_Gce_CondicoesCompra.strCodArtigo = Mov_Venda_Lin.strCodArtigo 
          AND Tbl_Gce_CondicoesCompra.intCodFornecedor = 124 
INNER JOIN 
    Tbl_Gce_Artigos ON Tbl_Gce_Artigos.strcodigo = Mov_Venda_Lin.strCodArtigo 
LEFT JOIN 
    Tbl_Gce_Vendedores ON Tbl_Gce_Vendedores.intcodigo = Mov_Venda_Cab.intcodvendedor 
INNER JOIN 
    Tbl_Tipos_Documentos ON Tbl_Tipos_Documentos.strAbreviatura = Mov_Venda_Cab.strAbrevTpDoc 

讓我們來看看WHERE條款:

WHERE 
    Mov_Venda_cab.dtmdata >= (select dtmUltimoEnvio 
           from USR464_Tbl_GruposConsultas 
           where codigo = 1 and bitInativo = 0) 
    AND Mov_Venda_cab.dtmdata <= CONVERT(date, getdate()) 
    AND Tbl_Gce_ArtigosFamilias.strCodFamilia IN (17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29) 
    AND (tbl_clientes.CA_danone IS NULL OR tbl_clientes.ca_danone = 0) 
    AND mov_venda_cab.bitAnulado = 0 
    AND Tbl_Tipos_Documentos.bitAfectaVolumeVnd = 1 
ORDER BY 
    Mov_Venda_cab.dtmdata 

我想要檢索的日期這where條款,此日期爲另一個表

如果我執行

(select dtmUltimoEnvio from USR464_Tbl_GruposConsultas where codigo=1 and bitInativo=0) 

這需要不到一秒鐘的時間 - 但是如果我執行這個整個查詢,它會花費太多的時間11秒

where子句中,如果我手動添加日期過濾器(將select移除到另一個表),查詢也會在不到一秒的時間內執行。

例如:

WHERE 
    Mov_Venda_cab.dtmdata >= '2015-01-01' 

我試過

,而不是使這個

WHERE 
     Mov_Venda_cab.dtmdata>=(select dtmUltimoEnvio from USR464_Tbl_GruposConsultas where codigo=1 and bitInativo=0) 

我試圖內加入表和使用領域這樣

inner join USR464_Tbl_GruposConsultas on 
USR464_Tbl_GruposConsultas.bitInativo=0 
and USR464_Tbl_GruposConsultas.codigo=1 

WHERE 
Mov_Venda_cab.dtmdata>=USR464_Tbl_GruposConsultas.dtmUltimoEnvio 

但它也需要11秒

但是,如果我聲明一個變量第一次像這樣

DECLARE @dataultimoenvio date 
SET @dataultimoenvio = convert(date,(select top 1 dtmUltimoEnvio from USR464_Tbl_GruposConsultas where codigo=1 and bitInativo=0)) 

然後使用該變量在where子句這樣

WHERE 
Mov_Venda_cab.dtmdata>[email protected] 

這需要3秒運行..還是太多了。

因爲在我想讓此查​​詢運行的計算機上需要大約1分鐘的這3秒查詢和5分鐘的11秒查詢,因此我的計算機需要3秒。

你是否有更好的選擇從另一個表中引入變量?

爲什麼每個查詢分別在大約0.1秒內運行並一起佔用這麼長時間?

+4

通過突出顯示查詢並按下Ctrl + L來查看估計的執行計劃。這應該讓你知道查詢的哪一部分需要很長時間。 – coderboy

回答

0

您確實需要在查詢中開始使用別名。發佈時,您的查詢是文本牆,因此幾乎不可能解密。此外,不包括別名已被棄用,並將在未來需要。這裏是你使用別名和一些非常基本格式的查詢。

SELECT 
    c.strNome as Cliente, 
    c.strPostal as 'Código Postal', 
    c.strLocalidade as Cidade, 
    mvc.dtmdata as 'Data Fatura', 
    c.strNumContrib as 'N. Contribuinte', 
    mvl.strCodArtigo as Artigo, 
    cc.strCodArtigoFornecedor as 'Artigo Fornecedor', 
    mvl.strDescArtigo as 'Designação 1', 
    mvl.fltQuantidade*mvc.intSinal as 'Qtd. Faturada', 
    ga.strAbrevMedVnd as 'Unid. Venda', 
    mvl.fltvalorliquido/mvl.fltQuantidade as 'Prç.Liq.', 
    mvl.fltvalorliquido as 'Montante Liquido', 
    v.strnome as Vendedor 
FROM Mov_Venda_Lin mvl 
INNER JOIN Tbl_Gce_ArtigosFamilias af ON mvl.strCodArtigo = af.strCodArtigo 
INNER JOIN Mov_Venda_Cab mvc ON mvc.strCodSeccao = mvl.strCodSeccao 
    AND mvc.strAbrevTpDoc = mvl.strAbrevTpDoc 
    AND mvc.strCodExercicio = mvl.strCodExercicio 
    AND mvc.intNumero = mvl.INTNUMERO 
INNER JOIN Tbl_Clientes c ON c.intCodigo = mvc.intCodEntidade 
INNER JOIN Tbl_Gce_CondicoesCompra cc ON cc.strCodArtigo = mvl.strCodArtigo 
    and cc.intCodFornecedor = 124 
INNER JOIN Tbl_Gce_Artigos ga ON ga.strcodigo=mvl.strCodArtigo 
LEFT JOIN Tbl_Gce_Vendedores v ON v.intcodigo=mvc.intcodvendedor 
inner join Tbl_Tipos_Documentos d on d.strAbreviatura=mvc.strAbrevTpDoc 
WHERE 
    mvc.dtmdata >= (select dtmUltimoEnvio from USR464_Tbl_GruposConsultas where codigo = 1 and bitInativo = 0) 
    AND mvc.dtmdata <= CONVERT(date, getdate()) 
    AND af.strCodFamilia in (17,18,19,20,21,22,23,24,25,26,27,28,29) 
    and (c.CA_danone is NULL or c.ca_danone = 0) 
    and mvc.bitAnulado = 0 
    and d.bitAfectaVolumeVnd = 1 
order by mvc.dtmdata 

我沒有看到任何明顯的表現瓶頸。它最有可能歸結爲表結構和索引策略。至少執行計劃將有助於找到這裏的瓶頸。