При простом соединении из трех таблиц производительность запросов резко меняется, если включить ORDER BY, даже если строки не возвращены. Реальный сценарий проблемы занимает 30 секунд, чтобы вернуть ноль строк, но он мгновенный, когда ORDER BY не включен. Почему?
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 */
Я понимаю, что у меня мог бы быть индекс на bigtable.smallGuidId, но, я думаю, это действительно ухудшило бы ситуацию в этом случае.
Вот скрипт для создания / заполнения таблиц для тестирования. Любопытно, что кажется, что smalltable имеет поле nvarchar (max). Также, кажется, имеет значение, что я присоединяюсь к bigtable с помощью guid (который, я думаю, заставляет использовать хеш-сопоставление).
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 и 2008R2 с теми же результатами.