Ben böyle bir tablo var:
CREATE TABLE Updates
(
UpdateId INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
ObjectId INT NOT NULL
)
Temelde, kimliği giderek artan nesneler için güncellemeleri izlemek.
Bu tablonun tüketicisi, belirli bir sıralamadan UpdateId
başlayıp belirli bir sıradan başlayarak 100 farklı nesne tanıtıcısı seçecektir UpdateId
. Esasen, kaldığı yerden devam edin ve ardından güncellemeleri sorgulayın.
Ben sadece sorguları yazarak maksimum optimum sorgu planı oluşturmak mümkün oldum çünkü ilginç bir optimizasyon problemi olarak bu saptadığımız gerçekleşmesi Ben endeksler nedeniyle istiyorum, ama yok ne yapacağını garanti ne istiyorum:
SELECT DISTINCT TOP 100 ObjectId
FROM Updates
WHERE UpdateId > @fromUpdateId
@fromUpdateId
Saklı yordam parametresi nerede .
Bir planla:
SELECT <- TOP <- Hash match (flow distinct, 100 rows touched) <- Index seek
UpdateId
Kullanılan endeks arayışı nedeniyle , sonuçlar zaten güzel ve istediğim gibi en düşük en yüksek güncelleme kimliğinden sipariş. Ve bu akış farklı bir plan oluşturuyor , istediğim bu. Ama sipariş açıkçası garantili davranış değil, bu yüzden kullanmak istemiyorum.
Bu hile aynı sorgu planıyla da sonuçlanır (yedek TOP ile olsa da):
WITH ids AS
(
SELECT ObjectId
FROM Updates
WHERE UpdateId > @fromUpdateId
ORDER BY UpdateId OFFSET 0 ROWS
)
SELECT DISTINCT TOP 100 ObjectId FROM ids
Gerçi, bu gerçekten sipariş garanti edip etmediğinden emin değilim (ve şüpheli değilim).
SQL Server basitleştirmek için yeterince akıllı olacağını umdum bir sorgu, ama çok kötü bir sorgu planı üreten sonuçlanır:
SELECT TOP 100 ObjectId
FROM Updates
WHERE UpdateId > @fromUpdateId
GROUP BY ObjectId
ORDER BY MIN(UpdateId)
Bir planla:
SELECT <- Top N Sort <- Hash Match aggregate (50,000+ rows touched) <- Index Seek
Ben bir dizin arama UpdateId
ve yinelenen s kaldırmak için farklı bir akış ile optimal bir plan oluşturmak için bir yol bulmaya çalışıyorum ObjectId
. Herhangi bir fikir?
İsterseniz örnek veriler . Nesnelerin nadiren birden fazla güncellemesi olacak ve 100 satırlık bir kümede neredeyse hiç birden fazla içermemelidir , bu yüzden bilmediğim daha iyi bir şey olmadığı sürece bir akıştan sonrayım ? Ancak, tek bir ObjectId
tabloda 100'den fazla satır olmayacağının garantisi yoktur . Tablo 1.000.000'dan fazla satıra sahiptir ve hızla büyümesi beklenmektedir.
Bu kullanıcının uygun bir sonraki bulmak için başka bir yolu olduğunu varsayalım @fromUpdateId
. Bu sorguda döndürmenize gerek yok.