ฉันกำลังทดลองกับดัชนีเพื่อเร่งความเร็วของสิ่งต่าง ๆ แต่ในกรณีของการเข้าร่วมดัชนีจะไม่ปรับปรุงเวลาดำเนินการแบบสอบถามและในบางกรณีจะทำให้สิ่งต่าง ๆ ช้าลง
แบบสอบถามเพื่อสร้างตารางทดสอบและกรอกข้อมูลคือ:
CREATE TABLE [dbo].[IndexTestTable](
[id] [int] IDENTITY(1,1) PRIMARY KEY,
[Name] [nvarchar](20) NULL,
[val1] [bigint] NULL,
[val2] [bigint] NULL)
DECLARE @counter INT;
SET @counter = 1;
WHILE @counter < 500000
BEGIN
INSERT INTO IndexTestTable
(
-- id -- this column value is auto-generated
NAME,
val1,
val2
)
VALUES
(
'Name' + CAST((@counter % 100) AS NVARCHAR),
RAND() * 10000,
RAND() * 20000
);
SET @counter = @counter + 1;
END
-- Index in question
CREATE NONCLUSTERED INDEX [IndexA] ON [dbo].[IndexTestTable]
(
[Name] ASC
)
INCLUDE ( [id],
[val1],
[val2])
ตอนนี้แบบสอบถาม 1 ซึ่งได้รับการปรับปรุง (เพียงเล็กน้อยเท่านั้น แต่การปรับปรุงมีความสอดคล้องกัน) คือ:
SELECT *
FROM IndexTestTable I1
JOIN IndexTestTable I2
ON I1.ID = I2.ID
WHERE I1.Name = 'Name1'
สถิติและแผนการดำเนินการโดยไม่มีดัชนี (ในกรณีนี้ตารางจะใช้ดัชนีคลัสเตอร์เริ่มต้น):
(5000 row(s) affected)
Table 'IndexTestTable'. Scan count 2, logical reads 5580, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 109 ms, elapsed time = 294 ms.
ขณะนี้เปิดใช้งานดัชนีแล้ว:
(5000 row(s) affected)
Table 'IndexTestTable'. Scan count 2, logical reads 2819, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 94 ms, elapsed time = 231 ms.
ตอนนี้เคียวรีที่ช้าลงเนื่องจากดัชนี (เคียวรีนั้นไม่มีความหมายเนื่องจากถูกสร้างขึ้นสำหรับการทดสอบเท่านั้น):
SELECT I1.Name,
SUM(I1.val1),
SUM(I1.val2),
MIN(I2.Name),
SUM(I2.val1),
SUM(I2.val2)
FROM IndexTestTable I1
JOIN IndexTestTable I2
ON I1.Name = I2.Name
WHERE
I2.Name = 'Name1'
GROUP BY
I1.Name
ด้วยการเปิดใช้งานดัชนีคลัสเตอร์:
(1 row(s) affected)
Table 'IndexTestTable'. Scan count 4, logical reads 60, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 1, logical reads 155106, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 17207 ms, elapsed time = 17337 ms.
ขณะนี้มีการปิดใช้งานดัชนี:
(1 row(s) affected)
Table 'IndexTestTable'. Scan count 5, logical reads 8642, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 2, logical reads 165212, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.
(1 row(s) affected)
SQL Server Execution Times:
CPU time = 17691 ms, elapsed time = 9073 ms.
คำถามคือ:
- แม้ว่า SQL Server จะแนะนำดัชนี แต่ทำไมมันถึงทำให้ช้าลงด้วยความแตกต่างที่สำคัญ?
- การเข้าร่วม Nested Loop คืออะไรซึ่งใช้เวลาส่วนใหญ่และวิธีการปรับปรุงเวลาดำเนินการ
- มีบางอย่างที่ฉันทำผิดหรือพลาด?
- ด้วยดัชนีเริ่มต้น (บนคีย์หลักเท่านั้น) เหตุใดจึงใช้เวลาน้อยลงและมีดัชนีที่ไม่เป็นคลัสเตอร์สำหรับแต่ละแถวในตารางการเข้าร่วมแถวของตารางที่เข้าร่วมควรจะพบได้เร็วขึ้นเนื่องจากการเข้าร่วมอยู่ในคอลัมน์ชื่อที่ สร้างดัชนีแล้ว สิ่งนี้สะท้อนให้เห็นในแผนการดำเนินการแบบสอบถามและค่าดัชนีค้นหาน้อยกว่าเมื่อดัชนีใช้งานอยู่ แต่ทำไมยังช้ากว่า อะไรคือสิ่งที่อยู่ใน Nested Loop ด้านนอกซ้ายเข้าร่วมที่ทำให้เกิดการชะลอตัว?
ใช้ SQL Server 2012