Sql-Server
幫助我更好地設計查詢,以便獲得更高的性能
我需要在數據庫中找到所謂的第一個條目,以獲取有關其合作夥伴的項目。我寫了查詢,它給了我正確的結果,但性能很糟糕。
我懷疑我錯過了概念,因此這個查詢可以寫得更好。所以我請你幫我重新設計這個查詢以獲得更好的性能。
我執行的數據庫系統是 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 因為有子句。也許它會給查詢計劃者一個提示。那麼最大的問題是:為什麼外連接與子查詢?“ where .. stari_uazi.ART_ID is null ”是否意味著您要排除從子查詢返回的所有行?我懷疑子查詢是真正的殺手,因為對 DOC 的搜尋是無界的( DOC.DATUM <@od_datuma ),所以它可能會獲取大量的行,這些行沒有真正的目的,因為父查詢無論如何都排除了這些行。
我的猜測是,如果您抑制子查詢(左外連接..),您將獲得與您想要的非常接近的東西,而且速度要快得多。如果您需要抑制結果集中的某些行,您可以將它們放在臨時表中並在之後刪除它們,這可能比外部連接子查詢更快。
更新:因此,如果您只想保留 @od / @do _datum 之間的行,請刪除左連接並添加條件
where DOC.DATUM between @od_ and @do_
您將獲得相同的結果,並且速度會快得多。