我有这个问题:
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>=@dataultimoenvio
这需要3秒钟才能运行......而且还是太多了。
在我的计算机上3秒,因为在我想要运行此查询的计算机上运行大约需要1分钟这个3秒查询和5分钟11秒查询。
您是否有更好的选择从另一个表中提取变量?
为什么每个查询分别在大约0.1秒内运行并且一起需要这么长?
答案 0 :(得分: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
我没有看到任何明显的性能瓶颈。它最有可能归结为表结构和索引策略。至少执行计划有助于找到这里的瓶颈。