Basit üç tablo birleşimi göz önüne alındığında, ORDER BY dahil edildiğinde, hiçbir satır döndürülmemiş olsa bile sorgu performansı önemli ölçüde değişir. Gerçek sorun senaryosu sıfır satır döndürmek için 30 saniye sürer, ancak ORDER BY dahil edilmediğinde anında olur. Neden?
SELECT *
FROM tinytable t /* one narrow row */
JOIN smalltable s on t.id=s.tinyId /* one narrow row */
JOIN bigtable b on b.smallGuidId=s.GuidId /* a million narrow rows */
WHERE t.foreignId=3 /* doesn't match */
ORDER BY b.CreatedUtc /* try with and without this ORDER BY */
Ben bigtable.smallGuidId bir dizin olabilir anlıyorum, ama, aslında bu durumda daha da kötüleştireceğine inanıyorum.
İşte test için tabloları oluşturmak / doldurmak için komut dosyası. İlginçtir ki, smalltable'ın bir nvarchar (max) alanına sahip olduğu önemli gibi görünüyor. Ayrıca bigtable üzerinde bir rehber ile katılmamın önemli olduğu anlaşılıyor (sanırım hash eşleşmesini kullanmak istiyor).
CREATE TABLE tinytable
(
id INT PRIMARY KEY IDENTITY(1, 1),
foreignId INT NOT NULL
)
CREATE TABLE smalltable
(
id INT PRIMARY KEY IDENTITY(1, 1),
GuidId UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID(),
tinyId INT NOT NULL,
Magic NVARCHAR(max) NOT NULL DEFAULT ''
)
CREATE TABLE bigtable
(
id INT PRIMARY KEY IDENTITY(1, 1),
CreatedUtc DATETIME NOT NULL DEFAULT GETUTCDATE(),
smallGuidId UNIQUEIDENTIFIER NOT NULL
)
INSERT tinytable
(foreignId)
VALUES(7)
INSERT smalltable
(tinyId)
VALUES(1)
-- make a million rows
DECLARE @i INT;
SET @i=20;
INSERT bigtable
(smallGuidId)
SELECT GuidId
FROM smalltable;
WHILE @i > 0
BEGIN
INSERT bigtable
(smallGuidId)
SELECT smallGuidId
FROM bigtable;
SET @i=@i - 1;
END
SQL 2005, 2008 ve 2008R2'de aynı sonuçları test ettim.