Kümelenmiş Dizin Tarama Yürütme Sayısı neden bu kadar yüksek?


15

Bir sorgu planı 1316 kez bir kümelenmiş dizin tarama yürütürken, diğer 1 kez yürütür dışında aynı sorgu planı üreten iki benzer sorguları var.

İki sorgu arasındaki tek fark farklı tarih ölçütleridir. Uzun süren sorgu aslında tarih ölçütlerini daraltır ve daha az veri geri alır.

Her iki sorguda da yardımcı olacak bazı dizinler belirledim, ancak sadece Kümelenmiş Dizin Tarama işlecinin neden 1316 kez yürüttüğünü, 1 kez yürüttüğü ile hemen hemen aynı olan bir sorgu üzerinde yürütmek istediğini anlamak istiyorum.

Taranan PK istatistiklerini kontrol ettim ve nispeten günceller.

Orijinal sorgu:

select distinct FIR_Incident.IncidentID
from FIR_Incident
left join (
    select incident_id as exported_incident_id
    from postnfirssummary
) exported_incidents on exported_incidents.exported_incident_id = fir_incident.incidentid
where FI_IncidentDate between '2011-06-01 00:00:00.000' and '2011-07-01 00:00:00.000'
    and exported_incidents.exported_incident_id is not null

Bu planı oluşturur: resim açıklamasını buraya girin

Tarih aralığı ölçütlerini daralttıktan sonra:

select distinct FIR_Incident.IncidentID
from FIR_Incident
left join (
    select incident_id as exported_incident_id
    from postnfirssummary
) exported_incidents on exported_incidents.exported_incident_id = fir_incident.incidentid
where FI_IncidentDate between '2011-07-01 00:00:00.000' and '2011-07-02 00:00:00.000'
    and exported_incidents.exported_incident_id is not null

Bu planı oluşturur: resim açıklamasını buraya girin


Sorgularınızı görüntü dosyaları yerine bir kod bloğuna kopyalayabilir / yapıştırabilir misiniz?
Eric Humphrey - lotsahelp

Tabii - Her bir planı oluşturan sorguları ekledim.
Seibar

Kümelenmiş dizin taraması hangi tabloda gerçekleşiyor?
Eric Humphrey - lotsahelp

Kümelenmiş Dizin taraması sol birleşimdeki alt sorguda (PostNFIRSSummary)
Seibar

1
Muhtemelen istatistikler en son güncellendiğinde, FI_IncidentDate between '2011-07-01 00:00:00.000' and '2011-07-02 00:00:00.000'ölçütleri karşılayan yalnızca sıfır veya bir satır vardı ve o zamandan beri o aralıkta orantısız sayıda ekleme yapıldı. Bu tarih aralığı için yalnızca 1,07 yürütme gerekeceğini tahmin ediyor. Gerçekte ortaya çıkan 1,316 değil.
Martin Smith

Yanıtlar:


9

Taramadan sonra JOIN bir ipucu verir: son birleştirmenin bir tarafında daha az satır olduğunda (elbette sağdan sola okuma), iyileştirici bir "karma birleşimi" değil "iç içe bir döngü" seçer.

Ancak, buna bakmadan önce Anahtar Arama ve DISTINCT'i ortadan kaldırmayı hedefliyorum.

  • Anahtar arama: FIR_Incident'deki dizininiz büyük olasılıkla (FI_IncidentDate, incidentid)veya başka şekilde olmalıdır. Veya ikisine birden sahip olun ve hangisinin daha sık kullanıldığını görün (her ikisi de olabilir)

  • Bunun DISTINCTbir sonucudur LEFT JOIN ... IS NOT NULL. Optimize edici zaten kaldırmış (planlar son JOIN'de "sol yarı birleşimler" bıraktı) ama netlik için EXISTS'i kullanardım

Gibi bir şey:

select 
    F.IncidentID
from 
    FIR_Incident F
where 
    exists (SELECT * FROM postnfirssummary P
           WHERE P.incident_id = F.incidentid)
    AND
    F.FI_IncidentDate between '2011-07-01 00:00:00.000' and '2011-07-02 00:00:00.000'

SQL Server'ın karma birleştirmeyi kullanmasını sağlamak için plan kılavuzlarını ve JOIN ipuçlarını da kullanabilirsiniz , ancak önce normal şekilde çalışmasını sağlamaya çalışın: bir rehber veya ipucu muhtemelen sadece test için yararlı olmadığından zaman testine dayanmaz ve gelecekte yürüttüğünüz sorgular, gelecekte değil

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.