Aynı şekilde adlandırılmış, yazılmış ve dizine eklenmiş anahtar sütunlara sahip iki tablom var. Bunlardan biri benzersiz kümelenmiş bir dizine, diğeri ise benzersiz değil .
Test kurulum
Bazı gerçekçi istatistikler içeren kurulum betiği:
DROP TABLE IF EXISTS #left;
DROP TABLE IF EXISTS #right;
CREATE TABLE #left (
a char(4) NOT NULL,
b char(2) NOT NULL,
c varchar(13) NOT NULL,
d bit NOT NULL,
e char(4) NOT NULL,
f char(25) NULL,
g char(25) NOT NULL,
h char(25) NULL
--- and a few other columns
);
CREATE UNIQUE CLUSTERED INDEX IX ON #left (a, b, c, d, e, f, g, h)
UPDATE STATISTICS #left WITH ROWCOUNT=63800000, PAGECOUNT=186000;
CREATE TABLE #right (
a char(4) NOT NULL,
b char(2) NOT NULL,
c varchar(13) NOT NULL,
d bit NOT NULL,
e char(4) NOT NULL,
f char(25) NULL,
g char(25) NOT NULL,
h char(25) NULL
--- and a few other columns
);
CREATE CLUSTERED INDEX IX ON #right (a, b, c, d, e, f, g, h)
UPDATE STATISTICS #right WITH ROWCOUNT=55700000, PAGECOUNT=128000;
Repro
Kümelenme anahtarlarındaki bu iki tabloya katıldığımda, bir-çok MERGE katılımını beklerim, şöyle:
SELECT *
FROM #left AS l
LEFT JOIN #right AS r ON
l.a=r.a AND
l.b=r.b AND
l.c=r.c AND
l.d=r.d AND
l.e=r.e AND
l.f=r.f AND
l.g=r.g AND
l.h=r.h
WHERE l.a='2018';
İstediğim sorgu planı bu:
(Uyarıları dikkate almayın, sahte istatistiklerle ilgili olmalıdırlar.)
Ancak, birleşimdeki sütunların sırasını değiştirirsem, bunun gibi:
SELECT *
FROM #left AS l
LEFT JOIN #right AS r ON
l.c=r.c AND -- used to be third
l.a=r.a AND -- used to be first
l.b=r.b AND -- used to be second
l.d=r.d AND
l.e=r.e AND
l.f=r.f AND
l.g=r.g AND
l.h=r.h
WHERE l.a='2018';
... bu olur:
Sort işleci, akışları birleştirme işleminin bildirilmiş sırasına göre, yani c, a, b, d, e, f, g, h
sorgu planıma engelleme işlemi ekleyen gibi görünüyor .
Baktığım şeyler
- Sütunları
NOT NULL
aynı sonuçlarla değiştirmeyi denedim . - Orijinal tablo birlikte oluşturuldu
ANSI_PADDING OFF
, ancak birlikte oluşturulmasıANSI_PADDING ON
bu planı etkilemez. - Değişim
INNER JOIN
yerine bunun yerine denedimLEFT JOIN
. - Bunu bir 2014 SP2 Enterprise'da keşfettim, 2017 Geliştirici (şu anki CU) üzerinde bir repro oluşturdum.
- WHERE yan tümcesini ana dizin sütunundan kaldırmak iyi bir plan oluşturur, ancak sonuçları etkileyebilir .. :)
Sonunda soruya geçiyoruz
- Bu kasıtlı mı?
- Sorgu değiştirmeden sıralama ortadan kaldırabilir miyim (ki satıcı kodu, bu yüzden gerçekten tercih ediyorum ...). Tablo ve indeksleri değiştirebilirim.