간단한 3 개의 테이블 조인이 주어지면 ORDER BY가 행을 반환하지 않아도 포함되면 쿼리 성능이 크게 변경됩니다. 실제 문제 시나리오는 30 초가 걸리고 0 개의 행을 반환하지만 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) 필드가 있다는 것이 중요합니다. 또한 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에서 동일한 결과를 테스트했습니다.



