Đưa ra một phép nối ba bảng đơn giản, hiệu năng truy vấn thay đổi mạnh mẽ khi ORDER BY được bao gồm ngay cả khi không có hàng nào được trả về. Kịch bản vấn đề thực tế mất 30 giây để trả về các hàng 0 nhưng ngay lập tức khi không bao gồm ORDER BY. Tại sao?
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 */
Tôi hiểu rằng tôi có thể có một chỉ mục trên bigtable.smallGuidId, nhưng, tôi tin rằng điều đó thực sự sẽ làm cho nó tồi tệ hơn trong trường hợp này.
Đây là kịch bản để tạo / điền vào các bảng để kiểm tra. Thật kỳ lạ, có vẻ như vấn đề là smalltable có trường nvarchar (max). Có vẻ như vấn đề là tôi tham gia vào bigtable với một hướng dẫn (mà tôi đoán làm cho nó muốn sử dụng khớp băm).
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
Tôi đã thử nghiệm trên SQL 2005, 2008 và 2008R2 với cùng kết quả.