เมื่อใดที่ฉันควรสร้างดัชนีในฐานข้อมูลเชิงสัมพันธ์ (SQL Server)
มีกรณีสำหรับการสร้างดัชนีใหม่เป็นประจำหรือไม่?
เมื่อใดที่ฉันควรสร้างดัชนีในฐานข้อมูลเชิงสัมพันธ์ (SQL Server)
มีกรณีสำหรับการสร้างดัชนีใหม่เป็นประจำหรือไม่?
คำตอบ:
ในความเสี่ยงของการเป็นคนทั่วไปในคำตอบของฉันฉันจะบอกว่าคุณควรใช้กระบวนการบำรุงรักษาดัชนีเป็นประจำ อย่างไรก็ตามกระบวนการบำรุงรักษาดัชนีของคุณควรสร้าง / จัดระเบียบดัชนีที่จำเป็นต้องใช้ใหม่โดยเฉพาะ
สิ่งนี้นำเสนอคำถาม: ดัชนีจะต้องถูกสร้างใหม่หรือจัดโครงสร้างใหม่เมื่อใด Rolando ได้สัมผัสกับสิ่งนี้อย่างดี อีกครั้งฉันเสี่ยงที่จะเป็นวงกว้างมาก ดัชนีต้องการการบำรุงรักษาเมื่อระดับการแตกแฟรกเมนต์ส่งผลกระทบต่อประสิทธิภาพ การกระจายตัวของระดับนี้อาจแตกต่างกันไปขึ้นอยู่กับขนาดและองค์ประกอบของดัชนี
เมื่อพูดถึง SQL Server ฉันมักจะเลือกขนาดดัชนีและระดับการกระจายตัวของดัชนี ณ จุดที่ฉันเริ่มทำการบำรุงรักษาดัชนี หากดัชนีมีน้อยกว่า 100 หน้าฉันจะไม่ทำการบำรุงรักษา
หากดัชนีอยู่ระหว่าง 10% ถึง 30% ฉันจะREORGANIZE
ดัชนีและUPDATE
สถิติ หากดัชนีมีมากกว่า 30% แยกส่วนผมจะREBUILD
ดัชนี - ไม่มีเช่นนี้ได้รับการดูแลโดยUPDATE STATISTICS
REBUILD
โปรดจำไว้ว่าการสร้างใหม่จะอัพเดตวัตถุสถิติที่เชื่อมโยงโดยตรงกับดัชนีเท่านั้น สถิติคอลัมน์อื่น ๆ จะต้องได้รับการดูแลแยกต่างหาก
คำตอบนี้เป็นวิธีที่ยาวมากที่จะพูดว่า: ใช่คุณควรทำการบำรุงรักษาดัชนีประจำ แต่เฉพาะกับดัชนีที่จำเป็นต้องใช้
เมื่อใดที่ฉันควรสร้างดัชนีในฐานข้อมูลเชิงสัมพันธ์ (เช่น SQL Server)
คุณควรสร้างดัชนีใหม่เมื่อมีการแยกส่วนอย่างมากจากเหตุการณ์พิเศษ ตัวอย่างเช่นคุณทำการโหลดข้อมูลจำนวนมากลงในตารางที่จัดทำดัชนี
มีกรณีสำหรับการสร้างดัชนีใหม่เป็นประจำหรือไม่?
แล้วถ้าดัชนีของคุณแยกส่วนเป็นประจำเนื่องจากกิจกรรมปกติล่ะ? คุณควรกำหนดเวลาการสร้างใหม่เป็นประจำหรือไม่ พวกเขาควรวิ่งบ่อยแค่ไหน?
Tom Kyteในหัวข้อ Ask Tom แบบคลาสสิคแนะนำ:
เวลาหน่วงระหว่างการสร้างดัชนีใหม่ควรอยู่ที่ประมาณตลอด
...
ไม่รู้จะพูดยังไงดีกว่านี้ - ดัชนีอยากอ้วนและใหญ่ด้วยพื้นที่พิเศษ อยู่ในคอลัมน์ที่คุณอัปเดต - ย้ายรายการดัชนีจากที่หนึ่งไปอีกที่หนึ่งในดัชนี วันหนึ่งแถวมีรหัส "A" ในวันถัดไปรหัสคือ "G" จากนั้น "Z" ตามด้วย "H" และอื่น ๆ ดังนั้นรายการดัชนีสำหรับแถวจะย้ายจากที่หนึ่งไปอีกที่หนึ่งในดัชนี เพราะมันต้องการพื้นที่ - ถ้าหากไม่มีพื้นที่เราแบ่งบล็อกออกเป็นสอง - และสร้างพื้นที่ ตอนนี้ดัชนีกำลังลดลง เมื่อเวลาผ่านไปดัชนีจะมีขนาด 2-3 เท่าเมื่อคุณเริ่มและเป็น "ครึ่งหนึ่งหรือมากกว่านั้นว่างเปล่า" แต่นั่นก็โอเคตั้งแต่คุณย้ายแถวไปมา ตอนนี้เมื่อเราย้ายแถวไปรอบ ๆ เราไม่จำเป็นต้องแยกบล็อกเพื่อให้มีพื้นที่ - ห้องว่างอยู่แล้ว
จากนั้นคุณจะมาพร้อมกับสร้างใหม่หรือลดลงและสร้างดัชนีใหม่ (ซึ่งมีผลเหมือนกัน - เพียงแค่การสร้างใหม่คือ "ปลอดภัย" - ไม่เสี่ยงต่อการสูญเสียดัชนีและสามารถทำได้เร็วขึ้นเนื่องจากดัชนีสามารถสร้างใหม่ได้โดย สแกนดัชนีที่มีอยู่แทนการสแกนตารางและการเรียงลำดับและสร้างดัชนีใหม่) ตอนนี้พื้นที่ว่างที่ดีทั้งหมดได้หายไปแล้ว เราเริ่มต้นกระบวนการแยกบล็อกทั้งหมดอีกครั้ง - นำเรากลับไปยังที่ที่เราเริ่ม
คุณประหยัดพื้นที่ไม่ได้
ดัชนีจะกลับมาเหมือนเดิม
คุณเพียงแค่ต้องเสียเวลาสร้างมันใหม่อีกครั้งทำให้วงจรนี้ซ้ำซาก
ตรรกะที่นี่คือเสียง แต่มันเอนเอียงกับโพรไฟล์โหลดที่อ่านหนัก
ดัชนี "อ้วน" (เช่นที่มีช่องว่างจำนวนมาก) ทำให้มีพื้นที่เพียงพอสำหรับแถวใหม่และแถวที่ถูกย้ายซึ่งจะช่วยลดการแยกหน้าและทำให้การเขียนของคุณรวดเร็ว อย่างไรก็ตามเมื่อคุณอ่านจากดัชนีไขมันนั้นคุณจะต้องอ่านหน้ามากขึ้นเพื่อรับข้อมูลเดียวกันเพราะตอนนี้คุณกลั่นกรองพื้นที่ว่างมากขึ้น สิ่งนี้จะทำให้การอ่านของคุณช้าลง
ดังนั้นในฐานข้อมูลแบบอ่านอย่างหนักคุณต้องการสร้างหรือจัดระเบียบดัชนีของคุณใหม่เป็นประจำ (บ่อยแค่ไหนและภายใต้เงื่อนไขใดแมตต์เอ็มมีคำตอบที่เป็นรูปธรรมสำหรับคำถามนี้อยู่แล้ว) ในฐานข้อมูลที่มีกิจกรรมการอ่านและการเขียนที่เทียบเท่ากันโดยประมาณหรือในฐานข้อมูลที่มีการเขียนอย่างหนัก สม่ำเสมอ
คนส่วนใหญ่สร้างพวกเขาใหม่เป็นประจำเพื่อที่พวกเขาจะไม่แยกส่วน เมื่อคุณต้องการสร้างใหม่ขึ้นอยู่กับว่าพวกเขาได้รับการแยกส่วนอย่างรวดเร็วเพียงใด ดัชนีบางตัวจะต้องถูกสร้างใหม่บ่อยๆ ตรวจสอบสคริปต์ที่ SQLFoolรวบรวมไว้ซึ่งจัดการการหาข้อมูลนี้ให้คุณได้มากมาย
ดังที่ระบุไว้ในคำตอบที่ยอมรับจาก Matt M กฎทั่วไปของหัวแม่มือคือดัชนีที่มีการแยกส่วนมากกว่า 30% ควรถูกสร้างใหม่
แบบสอบถามนี้จะช่วยให้คุณค้นหาจำนวนดัชนีที่มีการแยกส่วนมากกว่า 30% (เมื่อคุณมีคุณควรสร้างใหม่):
SELECT DB_NAME() AS DBName,
OBJECT_NAME(ind.object_id) AS TableName,
ind.name AS IndexName,
indexstats.index_type_desc AS IndexType,
indexstats.avg_fragmentation_in_percent,
indexstats.fragment_count,
indexstats.avg_fragment_size_in_pages,
SUM(p.rows) AS Rows
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, NULL) AS indexstats
INNER JOIN sys.indexes AS ind ON ( ind.object_id = indexstats.object_id
AND ind.index_id = indexstats.index_id)
INNER JOIN sys.partitions AS p ON ( ind.object_id = p.object_id
AND ind.index_id = p.index_id)
WHERE indexstats.avg_fragmentation_in_percent > 30
GROUP BY
OBJECT_NAME(ind.object_id),
ind.name,
indexstats.index_type_desc,
indexstats.avg_fragmentation_in_percent,
indexstats.fragment_count,
indexstats.avg_fragment_size_in_pages
ORDER BY indexstats.avg_fragmentation_in_percent DESC
เมื่อใดที่ฉันควรสร้างดัชนีใหม่
เมื่อเปอร์เซ็นต์การกระจายตัวของดัชนีมากกว่า 30%
มีกรณีสำหรับการสร้างดัชนีใหม่เป็นประจำหรือไม่?
ไม่มีกรณีดังกล่าว แต่โดยทั่วไปการทำดัชนีการบำรุงรักษาสัปดาห์ละครั้งในช่วงสุดสัปดาห์เป็นวิธีที่ดีที่สุดในการรักษาสภาพแวดล้อมให้คงที่
ฉันอยากจะแนะนำให้ใช้สคริปต์บำรุงรักษาจาก Ola Hallengren (สคริปต์บำรุงรักษาที่ดีที่สุด) ปรับแต่งสคริปต์ตามสภาพแวดล้อมของคุณและกำหนดเวลาให้สคริปต์ทำงานในช่วงสุดสัปดาห์
หมายเหตุ: โปรดอย่าลืมอัปเดตสถิติหลังจากสร้างดัชนีใหม่เนื่องจากการสร้างดัชนีใหม่ไม่ได้อัปเดตสถิติทั้งหมด
เช่นเดียวกับสิ่งต่างๆในไอทีมันขึ้นอยู่กับ คุณกำลังพยายามแก้ไขปัญหาอะไรด้วยการสร้างดัชนีใหม่ คุณช่วยแสดงให้เห็นว่ามันแก้ปัญหาได้จริง? ถ้าเป็นเช่นนั้นให้ปรับแต่งตัวเลขจนกว่าคุณจะพบจำนวนการบำรุงรักษาน้อยที่สุดที่คุณต้องทำเพื่อแก้ไขปัญหา
หากไม่สามารถแก้ไขปัญหาได้หรือสาเหตุที่คุณทำคือเพียงเอาใจตัวชี้วัดที่คุณตรวจสอบเพราะอาจทำให้สิ่งต่าง ๆ ดีขึ้นนั่นคือสิ่งที่คุณกำลังทำคือการเผา CPU และ IO และอาจทำให้ปัญหาของคุณแย่ลง
มีข้อโต้แย้งว่าการแก้ไขการแตกแฟรกเมนต์จะไม่สร้างความแตกต่างให้กับเซิร์ฟเวอร์ของคุณดังนั้นมันจึงคุ้มค่าที่จะทำอย่างสม่ำเสมอหรือไม่?
https://www.brentozar.com/archive/2017/12/index-maintenance-madness/