ฉันคิดว่าอย่างน้อยคำค้นหาต่อไปนี้จะช่วยให้คุณได้ใกล้ชิดมากขึ้น มันใช้ DMV ที่เปิดตัวใน SQL Server 2014: sys.dm_exec_query_profiles (และต้องขอบคุณ Martin Smith ที่แนะนำให้ฉันผ่าน DBA.StackExchange ที่เกี่ยวข้องนี้คำตอบ: ความคืบหน้าของคำสั่ง SELECT INTO :-)
โปรดทราบ:
!! คุณจะต้องเพิ่มSET STATISTICS PROFILE ON;
หรือSET STATISTICS XML ON;
ในชุดแบบสอบถามที่จะทำCREATE INDEX
(และวางไว้ก่อนที่จะCREATE INDEX
คำสั่งหากที่ไม่ชัดเจน) อื่นไม่มีแถวจะแสดงขึ้นใน DMV นี้ว่า SPID / session_id
!!
ตัวIN
ดำเนินการถูกใช้เพื่อกรองIndex Insert
แถวที่รวมอยู่จะเพิ่มTotalRows
ค่าซึ่งจะทำให้การคำนวณเอียงเนื่องจากแถวนั้นจะไม่แสดงแถวใด ๆ ที่ถูกประมวลผล
จำนวนแถวที่แสดงที่นี่ (เช่นTotalRows
) เป็นสองเท่าของจำนวนแถวของตารางเนื่องจากการดำเนินการสองขั้นตอนแต่ละอันทำงานบนแถวทั้งหมด: อันดับแรกคือ "การสแกนตาราง" หรือ "การสแกนดัชนีแบบกลุ่ม" และอันดับที่สองคือ "เรียงลำดับ" คุณจะเห็น "การสแกนตาราง" เมื่อสร้างดัชนีแบบกลุ่มหรือสร้างดัชนีแบบไม่รวมกลุ่มบนฮีป คุณจะเห็น "การสแกนดัชนีแบบกลุ่ม" เมื่อสร้างดัชนีแบบไม่รวมกลุ่มในดัชนีแบบกลุ่ม
ดูเหมือนว่าแบบสอบถามนี้จะไม่ทำงานเมื่อสร้างดัชนีที่กรองแล้ว ด้วยเหตุผลบางอย่างดัชนีที่กรองแล้ว a) ไม่มีขั้นตอน "เรียงลำดับ" และ b) row_count
เขตข้อมูลจะไม่เพิ่มขึ้นจาก 0
ไม่แน่ใจว่าฉันเคยทำการทดสอบมาก่อน แต่ตอนนี้การทดสอบของฉันระบุว่าดัชนีที่กรองถูกจับโดยแบบสอบถามนี้ หวาน. แม้ว่าเพียงแค่ระวังว่าจำนวนแถวอาจปิด (ฉันจะดูว่าฉันสามารถแก้ไขได้ในสักวันหนึ่ง)
เมื่อสร้างดัชนีแบบกลุ่มบนฮีปที่มีดัชนีแบบ nonClustered อยู่แล้วดัชนีแบบ nonClustered จะต้องถูกสร้างใหม่ (เพื่อสลับ RID - RowID - สำหรับคีย์ดัชนีแบบคลัสเตอร์และแต่ละดัชนีแบบไม่สร้างดัชนีใหม่จะ เป็นการดำเนินการแยกต่างหากและดังนั้นจึงไม่ปรากฏในสถิติที่ส่งคืนโดยแบบสอบถามนี้ในระหว่างการสร้างดัชนีแบบคลัสเตอร์
แบบสอบถามนี้ได้รับการทดสอบกับ:
- การสร้าง:
- ดัชนีแบบไม่รวมกลุ่มบนฮีป
- ดัชนีแบบคลัสเตอร์ (ไม่มีดัชนีแบบไม่รวมกลุ่ม)
- ดัชนีแบบไม่รวมกลุ่มบนดัชนี / ตารางแบบกลุ่ม
- ดัชนีแบบคลัสเตอร์เมื่อดัชนีแบบไม่รวมกลุ่มมีอยู่แล้ว
- ดัชนี NonClustered ที่ไม่ซ้ำในดัชนี / ตารางแบบคลัสเตอร์
- กำลังสร้างใหม่ (ตารางที่มีดัชนีแบบคลัสเตอร์และหนึ่งดัชนีแบบไม่รวมกลุ่มทดสอบบน SQL Server 2014, 2016, 2017 และ 2019) ผ่านทาง:
ALTER TABLE [schema_name].[table_name] REBUILD;
( เฉพาะดัชนีแบบกลุ่มเท่านั้นที่แสดงเมื่อใช้วิธีนี้ )
ALTER INDEX ALL ON [schema_name].[table_name] REBUILD;
ALTER INDEX [index_name] ON [schema_name].[table_name] REBUILD;
DECLARE @SPID INT = 51;
;WITH agg AS
(
SELECT SUM(qp.[row_count]) AS [RowsProcessed],
SUM(qp.[estimate_row_count]) AS [TotalRows],
MAX(qp.last_active_time) - MIN(qp.first_active_time) AS [ElapsedMS],
MAX(IIF(qp.[close_time] = 0 AND qp.[first_row_time] > 0,
[physical_operator_name],
N'<Transition>')) AS [CurrentStep]
FROM sys.dm_exec_query_profiles qp
WHERE qp.[physical_operator_name] IN (N'Table Scan', N'Clustered Index Scan',
N'Index Scan', N'Sort')
AND qp.[session_id] = @SPID
), comp AS
(
SELECT *,
([TotalRows] - [RowsProcessed]) AS [RowsLeft],
([ElapsedMS] / 1000.0) AS [ElapsedSeconds]
FROM agg
)
SELECT [CurrentStep],
[TotalRows],
[RowsProcessed],
[RowsLeft],
CONVERT(DECIMAL(5, 2),
(([RowsProcessed] * 1.0) / [TotalRows]) * 100) AS [PercentComplete],
[ElapsedSeconds],
(([ElapsedSeconds] / [RowsProcessed]) * [RowsLeft]) AS [EstimatedSecondsLeft],
DATEADD(SECOND,
(([ElapsedSeconds] / [RowsProcessed]) * [RowsLeft]),
GETDATE()) AS [EstimatedCompletionTime]
FROM comp;
ตัวอย่างผลลัพธ์:
Rows Percent Elapsed Estimated Estimated
CurrentStep TotalRows Processed RowsLeft Complete Seconds SecondsLeft CompletionTime
----------- --------- --------- -------- -------- ------- ----------- --------------
Clustered 11248640 4786937 6461703 42.56 4.89400 6.606223 2016-05-23
Index Scan 14:32:40.547
physical_operator_name
ตั้งค่าN'Index Scan'
มากกว่าหรือN'Table Scan'
N'Clustered Index Scan'
นอกจากนี้มันจะช้ามากเนื่องจากจะทำการค้นหา RID หลายครั้ง