我需要在数据库中找到所谓的第一个条目,以查找有关其合作伙伴的项目。我写了查询,它给了我正确的结果,但性能很差。
我怀疑我错过了受孕,因此这个查询可以写得更好。所以我请求你帮我重新设计这个查询以获得更好的性能。
我运行的数据库系统是Sql Server 2008
declare @od_datuma datetime
declare @do_datuma datetime
set @od_datuma='2011-12-01'
set @do_datuma='2011-12-31'
select
doc.PAR_ID
,sdo.art_id
,MIN(doc.id) as doc_id
from
dokumenti
inner join DOC on dokumenti.tip=DOC.TIP
inner join SDO on DOC.ID=SDO.DOC_ID
left outer join (
select par_id,art_id from dokumenti
inner join DOC on dokumenti.tip=DOC.TIP
inner join SDO on DOC.ID=SDO.DOC_ID
where dokumenti.NABAVA =1 and
dokumenti.KOL_UL=1 and
DOC.DATUM<@od_datuma
) as stari_uazi on DOC.PAR_ID=stari_uazi.PAR_ID and SDO.ART_ID=stari_uazi.ART_ID
where
dokumenti.NABAVA =1 and
dokumenti.KOL_UL=1 and
stari_uazi.ART_ID is null and
doc.datum between @od_datuma and @do_datuma
group by doc.PAR_ID,sdo.art_id
我首先要尝试的是添加 where doc.datum>=@od_datuma 和 doc.datum <=@do_datuma 因为 having 子句。也许它会给查询规划器一个提示。那么最大的问题是:为什么外部连接与子查询?“ where .. stari_uazi.ART_ID is null ”是否意味着您要排除从子查询返回的所有行?我怀疑子查询是真正的杀手,因为对 DOC 的搜索没有限制( DOC.DATUM <@od_datuma ),所以它可能会获取大量行,这些行没有真正的目的,因为父查询无论如何都排除了这些行..
我的猜测是,如果您抑制子查询(左外连接..),您将获得与您想要的非常接近的东西,而且速度要快得多。如果您需要从结果集中抑制某些行,您可以将它们放在一个临时表中,然后删除它们,这可能比外部连接子查询更快。
更新:因此,如果您只想保留@od / @do _datum 之间的行,请删除左连接并添加条件
where DOC.DATUM between @od_ and @do_
您将获得相同的结果,而且速度会快得多。