Bu SQL Server'da bir hatadır (2008'den 2014'e kadar dahil).
Hata raporum burada .
Filtreleme koşulu, artık bir belirteç olarak tarama operatörüne itilir, ancak sıralama için verilen bellek, ön filtre kardinalitesi tahminine dayanarak hatalı bir şekilde hesaplanır .
Sorunu göstermek için , Filtrenin tarama operatörüne itilmesini önlemek için 9130 (belgesiz ve desteksiz) izleme bayrağını kullanabiliriz . Sıralamaya verilen bellek artık, taramayı değil, Filtre çıktısının tahmini önem derecesine göre doğru:
SELECT
T.TID,
T.FilterMe,
T.SortMe,
T.Unused
FROM dbo.Test AS T
WHERE
T.FilterMe = 567
ORDER BY
T.SortMe
OPTION (QUERYTRACEON 9130); -- Not for production systems!
Bir üretim sistemi için , sorunlu plan şeklini önlemek için adımlar atılması gerekecektir (başka bir sütunda bir sıralama ile taramaya itilmiş bir filtre). Bunu yapmanın bir yolu, filtre koşulunda bir indeks sağlamak ve / veya gerekli sıralama düzenini sağlamaktır.
-- Index on the filter condition only
CREATE NONCLUSTERED INDEX IX_dbo_Test_FilterMe
ON dbo.Test (FilterMe);
Bu indeks yerinde iken, sıralama için istenen hafıza izni sadece 928KB'dir :
Daha da ileri giderek, aşağıdaki dizin tamamen sıralamadan kaçınabilir ( sıfır bellek izni):
-- Provides filtering and sort order
-- nvarchar(max) column deliberately not INCLUDEd
CREATE NONCLUSTERED INDEX IX_dbo_Test_FilterMe_SortMe
ON dbo.Test (FilterMe, SortMe);
SQL Server x64 Developer Edition'ın aşağıdaki sürümlerinde test edildi ve hata onaylandı:
2014 : 12.00.2430 (RTM CU4)
2012 : 11.00.5556 (SP2 CU3)
2008R2 : 10.50.6000 (SP3)
2008 : 10.00.6000 (SP4)
Bu edilmiş sabit içinde SQL Server 2016 Service Pack 1 . Sürüm notları şunları içerir:
VSTS hata numarası 8024987
Tablo taramaları ve aşağı dönük öngörme içeren dizin taramaları, ana operatör için bellek tahsisinden fazla değer verme eğilimindedir.
Test edildi ve onaylandı:
Microsoft SQL Server 2016 (SP1) - 13.0.4001.0 (X64) Developer Edition
Microsoft SQL Server 2014 (SP2-CU3) 12.0.5538.0 (X64) Developer Edition
Her iki CE modeli.