SQL Server: วิธีการติดตามความคืบหน้าของคำสั่ง CREATE INDEX?


36

SQL Server 2014, Std Ed

ฉันได้อ่านว่า percent_complete ใน dm_exec_requests ใช้ไม่ได้กับ CREATE INDEX และในทางปฏิบัติแล้ว percent_complete sticks ที่ 0 ดังนั้นมันจึงไม่ช่วย

ปัจจุบันฉันใช้วิธีการด้านล่างซึ่งอย่างน้อยก็แสดงให้ฉันเห็นการเคลื่อนไหว (ว่าการสร้างดัชนีไม่ได้ถูกบล็อก) แต่ฉันไม่มีความคิดถ้าฉัน% 10 ผ่านกระบวนการหรือ% 99

ฉันลองวิธีที่อธิบายไว้ที่นี่: https://dba.stackexchange.com/a/102545/6229 แต่มันแสดงให้เห็นว่าเวลาเสร็จสิ้นอย่างชัดเจนผิดปกติ (โดยทั่วไปจะแสดง 'ตอนนี้' เป็นเวลา 60 นาทีซึ่งฉันใช้เวลา 10 นาที )

ฉันจะได้รับเบาะแสได้อย่างไร

SELECT percent_complete, estimated_completion_time, reads, writes, logical_reads, text_size, *
FROM
sys.dm_exec_requests AS r
WHERE
r.session_id <> @@SPID
AND r.session_id = 58

คำตอบ:


56

ฉันคิดว่าอย่างน้อยคำค้นหาต่อไปนี้จะช่วยให้คุณได้ใกล้ชิดมากขึ้น มันใช้ 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 หลายครั้ง
ไบรอัน

ตอนนี้ถ้าเท่านั้นที่จะทำงานกับ ALTER INDEX ALL ON dbo.table REBUILD ..... <g>
Jonesome Reinstate Monica

1
BTW นี้ยังทำงานได้ดีในการตรวจสอบความคืบหน้าของการใช้การบีบอัดหน้าด้วย sys.dm_exec_query_profiles ค่อนข้างเจ๋ง
Todd Kleinhans

2
@JonesomeReinstateMonica ฉันเพิ่งอัพเดทข้อความค้นหาเล็กน้อย ดูเหมือนว่ามันไม่แน่นอนจับสร้างการดำเนินงานทั้งผ่านALTER INDEX ALLและแม้กระทั่ง ALTER TABLE .. REBUILD(บางส่วน) โปรดตรวจสอบ :-)
โซโลมอน Rutzky

1
สวัสดี @RoniVered ฉันเพิ่งอัพเดตเคียวรีในคำตอบเล็กน้อยเพื่อที่จะรวบรวมการสร้างดัชนี NonClustered ใหม่ ฉันทดสอบทั้งสองประเภทของคำสั่ง (แม้ว่าจะไม่ใช่ DBCC ฉันแค่คิดถึงมัน) และใน SQL Server 2019, 2017, 2016, และ 2014 ดูเหมือนว่าจะทำงานเหมือนกันทุกอย่าง :-)
โซโลมอน Rutzky
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.