Neden dizin arama doğru sayıda satır tahmin edebilir ve sıralama operatörü edemiyor?


11

Yüklemede bir işlevi kullanan bir sorgu var, böyle bir şey:

commentType = 'EL'
AND commentDateTime >= DATEADD(month,datediff(month,0,getdate()) - 13,0)

40K satır olan commentType üzerinde filtrelenmiş bir dizin var ve sorguyu çalıştırdığınızda, dizin arama için tahmini satır sayısı çok doğru (yaklaşık 11 K), ama sonraki adım (sıralama operatörü) tamamen istatistikleri ve yok sayar filtrelenmiş dizindeki toplam satır sayısını tahmin eder.

Bu neden oluyor? Hırsızlığın temellerini biliyorum ve sadece akıl sağlığını yerine gerçek bir tarihe (2014-01-01) ve voila'ya göre akıl sağlığı için test ettim ... Sıra sıra sayısını doğru tahmin etmeye başladı ...

Bu neden oluyor ve nasıl düzeltebilirim? Sabit bir tarihi geçemem ...


DATEADD(month,datediff(month,0,getdate()) - 13,0)bana mantıklı gelmiyor. Bununla ne yapmaya çalışıyorsun? Geliştirilebilir / basitleştirilebilir mi?
Daniel Hutmacher

2
@Daniel Bu ayın başlangıcı, 13 ay önce.
Aaron Bertrand

1
Ayrıca, lütfen sorunuzu, üzerinde bulunduğunuz SQL Server (?) Sürümünü yansıtacak şekilde düzenleyin. Bunun için etiketler kullanın.
Daniel Hutmacher

Bir DATEADD(month, -13, DATEADD(day, 1-DATEPART(day, SYSDATETIME()))fark olup olmadığını görebilir misin?
Daniel Hutmacher

Filtrelenmemiş bir dizininiz varsa, (commentType, commentDate)orada daha iyi davranır mı? Sadece filtrelenmiş dizinler bazen planlardaki farklı noktalardaki tahminleri yanlış raporlayabilir. Tahmin, filtrelenen dizindeki toplam sayıyı bildirerek çok daha iyi görünüyor, ancak aslında planın yanlış gösteriliyor olması.
Rob Farley

Yanıtlar:


9

DATEDIFF argümanlarından ikisini değiştiren bir tahminci hatası nedeniyle tahminlerinizin yanlış olduğuna inanıyorum. Burada bunun hakkında konuşuyorum:

Geçici çözüm, DATEDIFF (2008+) kullanmadan 13 ay önceki ilk günü hesaplamaktır:

DATEADD(MONTH, -13, DATEADD(DAY, 1-DATEPART(DAY,GETDATE()), CONVERT(DATE, GETDATE()));

Ben değilim pozitif (Filtrelenmeyen endeksler ile test etmedim, ve eminim sıralama aslında ne yaptığını değilim ya tahminini hitap edecek o planı ve / veya sorgunun dinlenmeden farklı tahminini sahip olmasının ).

Microsoft'un önerdiği düzeltme TF 4199 kullanmaktır, ancak burada yapmanız gerekenin bu olduğundan emin değilim:

Başka bir seçenek, aşağıdaki KB makalesinde düzeltildiğini iddia ettikleri için kullandığınız SQL Server sürümü için mutlak en son SP / CU'da olduğunuzdan emin olmaktır (yine de TF 4199'un kullanılmasını gerektirecektir) 2014 veya daha iyisi değilseniz):

Düzeltme aşağıdaki yapılarla elde edilebilir:

(Bir dahaki sefere, lütfen SELECT @@VERSIONsorunuzun sonuçlarını ekleyin.)

KB makalesinde, DATEDIFF'in senaryolarınızda olanların tam tersi olan satır sayısını hafife alabileceğini söylediğini göreceğim . Bu, düzeltmelerin sizin için geçerli olmadığı anlamına gelmez; Tahminler verilere ve baktığınız aralığa bağlı olarak her iki şekilde de gidebileceğinden, KB makale ifadelerinin yanlış olduğunu düşünüyorum.

Yukarıdaki blog yazım, değiştirmenin artık 2014 ve sonrasında gerçekleşmediğini doğruladı. Güvende olmak için, muhtemelen DATEDIFF'i yükleminizden çıkaracağım ve aralığınızın başlangıcını hesaplamak için farklı bir yöntem kullanacağım. Ben 4199 overkill veya kötü takas önlemek için dinamik SQL kullanarak önermiyoruz.


Yardım için teşekkürler ! Önerinizi denedim ve plan değişti. Daha önce böyle olmuştu: s16.postimg.org/t5j6o1yed/fix_wrong.png Senin dateiff'imi seninkiyle değiştirdikten sonra böyle oldu: postimg.org/image/5f725rj83 Bana verdiğin tüm URL'leri okuyacağım . Şerefe.
MrKudz
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.