Optimize Edici'nin davranışını daha iyi anlamak ve indeks biriktiricileri etrafındaki limitleri anlamak için bu soruyu soruyorum. 1 - 10000 arasında bir tamsayıyı bir yığına koyduğumu varsayalım:
CREATE TABLE X_10000 (ID INT NOT NULL);
truncate table X_10000;
INSERT INTO X_10000 WITH (TABLOCK)
SELECT TOP 10000 ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;
Ve iç içe geçmiş bir döngü ile birleşmeye zorlayın MAXDOP 1
:
SELECT *
FROM X_10000 a
INNER JOIN X_10000 b ON a.ID = b.ID
OPTION (LOOP JOIN, MAXDOP 1);
Bu, SQL Server'a yönelik yapılması gereken oldukça düşmanca bir eylemdir. İç içe geçmiş döngü birleşimleri, her iki tablonun da ilgili dizinleri olmadığında, genellikle iyi bir seçim değildir. İşte plan:
Sorgu makinemde 1300, masa makarasından 100000000 satır alındı. Ancak, sorgunun neden yavaş olması gerektiğini anlamıyorum. Sorgu en iyi duruma getiricisi, dizin makaraları aracılığıyla anında dizin oluşturma yeteneğine sahiptir . Bu sorgu bir dizin biriktirme için mükemmel bir aday olacak gibi görünüyor.
Aşağıdaki sorgu, birincisiyle aynı sonuçları döndürür, bir dizin biriktiricisine sahiptir ve bir saniyeden daha kısa bir sürede biter:
SELECT *
FROM X_10000 a
CROSS APPLY (SELECT TOP (9223372036854775807) b.ID FROM X_10000 b WHERE a.ID = b.ID) ca
OPTION (LOOP JOIN, MAXDOP 1);
Bu sorguda ayrıca bir dizin biriktirme var ve bir saniyeden daha kısa sürede bitiyor:
SELECT *
FROM X_10000 a
INNER JOIN X_10000 b ON a.ID >= b.ID AND a.ID <= b.ID
OPTION (LOOP JOIN, MAXDOP 1);
Orijinal sorgunda neden bir dizin biriktirme var? Dizin biriktirecek herhangi bir belgelenmiş veya belgelenmemiş ipucu veya iz bayrağı seti var mı? İlgili soruyu buldum , ancak sorumu tam olarak yanıtlamıyor ve gizemli iz bayrağının bu sorgu için çalışmasını sağlayamıyorum.