Dada uma associação simples de três tabelas, o desempenho da consulta muda drasticamente quando ORDER BY é incluído, mesmo sem nenhuma linha retornada. O cenário real do problema leva 30 segundos para retornar zero linhas, mas é instantâneo quando ORDER BY não está incluído. Por quê?
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 */
Entendo que eu poderia ter um índice em bigtable.smallGuidId, mas acredito que isso realmente pioraria as coisas nesse caso.
Aqui está o script para criar / preencher as tabelas para teste. Curiosamente, parece importar que smalltable tenha um campo nvarchar (max). Também parece importar que eu estou entrando na bigtable com um guid (o que eu acho que faz com que ele queira usar a correspondência de hash).
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
Eu testei no SQL 2005, 2008 e 2008R2 com os mesmos resultados.