2009-09-25 23 views
5

Pek çok tabağa (10-11) katılan oldukça karmaşık bir saklı yordamda hata ayıklamaya çalışıyorum. Ağacın bir kısmı için tahmin edilen satır sayısının, gerçek satır sayısından büyük ölçüde farklı olduğunu görüyorum - en kötü SQL sunucusunda, gerçekte 55.000 satır döndürüldüğünde, 1 satırın döndürüleceğini tahmin ediyor! Benim istatistiklerin tüm çeşitli tablolar üzerinde FULLSCAN ile güncel ve ben güncelledik istatistikler şunlardır - Bu yüzden SQL sunucusu, tahmini satır sayısını nasıl çalışır?

Ben çalışmak için çalışıyorum. Kullanıcı tanımlı işlevleri veya tablo değişkenlerini kullanmıyorum. SQL Server'ın görebildiğim kadarıyla, kaç satırın geri alınacağını tam olarak tahmin edebilmeli, ancak on binlerce RDI araması gerçekleştirecek bir plan seçmeye devam ediyor (sadece 1 gerçekleştirmek için bekleniyorsa). veya 2).

Tahmini satır sayısının neden bu kadar çok dışarı çıktığını anlamak için ne yapabilirim?

GÜNCELLEME: Yani Suspicous görünüyor ben özellikle bir düğüm buldum planına bakarak - onun bir tablo aşağıdaki predecate kullanarak bir masanın üzerine tarayın:

status <> 5 
AND [type] = 1 
OR [type] = 2 

Bu yüklem tüm tabloyu döndürür (630 satır - tablo, zayıf performansın kaynağı DEĞİLDİR) ancak SQL sunucusunun tahmini sayısı yalnızca 37'de olur. SQL sunucusu daha sonra RDI aramaları, dizin taramaları ve indeksleri ile birkaç iç içe döngüler yapar arar. Bu benim büyük yanlış hesaplamanın kaynağı olabilir mi? Daha hassas bir satır sayısını tahmin etmek için nasıl alabilirim? İstatistikleri zaten güncellenmiş yana

+0

Eğer tablo tanımını sonrası misiniz ve tam sorgu çözebilir sizin dizinleri yeniden? – Quassnoi

+0

Üzgünüz, ama gerçekten değil - çok büyük (250 satır sp + 10 tablo). – Justin

+3

Eğer yükleminiz tam olarak böyle ise (parantez yoksa), bir mantık sorununuz olabilir. AND, OR üzerinde önceliğe sahiptir. [status] <> 5 AND olmalıdır (type = 1 VEYA type type = 2) – GilaMonster

cevap

8

SQL Server böler (here den) aşağıdaki verileri kadar 200 gruplardan her dizin:

  • RANGE_HI_KEY

    Bir histogram adımının üst sınırını gösteren bir anahtar değer.

  • RANGE_ROWS

    kaç satır aralığı içine nasıl belirler (onlar RANGE_HI_KEY önceki daha küçük bu RANGE_HI_KEY daha küçük, ancak daha büyük).

  • EQ_ROWS

    kaç satır RANGE_HI_KEY tam eşittir nasıl belirler. aralığı içinde farklı bir değer başına satır

  • AVG_RANGE_ROWS

    ortalama sayısı.

  • DISTINCT_RANGE_ROWS

    farklı anahtar değerleri (RANGE_HI_KEY ve RANGE_HI_KEY kendisinden önce bir önceki anahtar dahil değil) bu aralık içinde kaç belirtir;

Genellikle en doldurulan değerler RANGE_HI_KEY girerler. Bununla birlikte, bunlar menzile girebilir ve bu da dağılımdaki çarpıklığa yol açabilir.

(diğerleri arasında) bu verileri düşünün: satır

anahtar değeri Sayısı

1   1 
2   1 
3   10000 
4   1 

SQL Server genellikle iki aralığı oluşturur: 1 bu istatistikleri yapar sonraki nüfuslu değere 3 ve 4 için : ( ), 1 satır var ve dizin erişimini kullanmak daha iyidir. 3 aralığın içinde giderse

Ancak istatistikler şunlardır:

RANGE_HI_KEY RANGE_ROWS EQ_ROWS AVG_RANGE_ROWS DISTINCT_RANGE_ROWS 
4    10002  1  3334   3 

iyileştirici orada anahtar 2 için 3334 satırları ve indeks erişim çok pahalı olduğunu düşünüyor.

+0

Tam taramayı içeren istatistikleri güncellemeyi çözemeseler bile bu sorunu nasıl çözebiliriz? – Meysam

+0

@Maysam: Sık kullandığınız yüklemeler için 'CREATE STATISTICS' kullanabilirsiniz. – Quassnoi

0

, ben koklama herhangi bir parametre ortadan kaldırmak için çalışacaktı: O her dizin için tutar, hangi istatistik kullanır

CREATE PROCEDURE xyz 
(
    @param1 int 
    ,@param2 varchar(10) 

)AS 

DECLARE @param_1 int 
     ,@param_2 varchar(10) 

SELECT @[email protected] 
     ,@[email protected] 

...complex query here.... 
...WHERE [email protected]_1 AND [email protected]_2.... 

go 
3

.

bir Veritabanı (UYARI her tablo tüm istatistiklerini güncellemek için (Ayrıca sigara endeksli sütunlarda istatistik oluşturabilirsiniz). Çok büyük veritabanları üzerinde biraz zaman alacak Bunu yapmayın DBA ile kontrol etmeden Üretim sunucularında ...): Eğer en aktif dizin (eklemeler ve silmeler yani çok yeniden inşa etmek için düzenli tarifeli işi) yoksa

exec sp_msforeachtable 'UPDATE STATISTICS ?' 

, sen yeniden düşünmelisiniz senin dizinler (yukarıdakiyle aynı uyarı geçerlidir):

exec sp_msforeachtable "DBCC DBREINDEX('?')" 
0

yanlış tahmin satırlar değer konuyu

İlgili konular