การแตกแฟรกเมนต์ไฟล์ฐานข้อมูล SQL ทางกายภาพ


19

ฉันรู้ว่ามีการกระจายตัวสามชนิดจริงๆ ที่ฉันต้องกังวลในฐานะ DBA:

  1. การกระจายตัวของดัชนีในไฟล์ข้อมูล SQL รวมถึงการกระจายตัวของดัชนี (ตาราง) คลัสเตอร์ ระบุสิ่งนี้โดยใช้ DBCC SHOWCONTIG (ใน SQL 2000) หรือ sys.dm_ db_ index_ physical_ stats (ในปี 2005+)

  2. การกระจายตัวของVLFภายในไฟล์บันทึก SQL รัน DBCC LOGINFO เพื่อดูว่า VLF มีกี่ไฟล์ในแต่ละไฟล์บันทึก SQL ของคุณ

  3. การแตกไฟล์แบบฟิสิคัลของไฟล์ฐานข้อมูลบนฮาร์ดไดรฟ์ วินิจฉัยสิ่งนี้โดยใช้ยูทิลิตี้ "Disk Defragmenter" ใน Windows (แรงบันดาลใจจากโพสต์บล็อกที่ยอดเยี่ยมนี้ )

ความสนใจจำนวนมากถูกจ่ายให้กับการแยกส่วนดัชนี (ดูคำตอบ Serverfault ที่ยอดเยี่ยมนี้จาก Paul Randall) ดังนั้นนั่นไม่ใช่จุดเน้นของคำถามของฉัน

ฉันรู้ว่าฉันสามารถป้องกันไม่ให้เกิดการกระจายตัวทางกายภาพ (และการกระจายตัวของ VLF) เมื่อฐานข้อมูลถูกสร้างขึ้นมาโดยการวางแผนการคาดแฟ้มข้อมูลและบันทึกขนาดที่เหมาะสมเพราะการกระจายตัวนี้เกิดขึ้นส่วนใหญ่มักจะมาจากบ่อยเติบโตและหดตัว แต่ผมมีคำถามบางอย่างเกี่ยวกับวิธีการแก้ไขการกระจายตัวทางกายภาพเมื่อมีการระบุ:

  • ก่อนอื่นการแยกส่วนทางกายภาพมีความเกี่ยวข้องกับ Enterprise SAN หรือไม่ ฉัน / ฉันควรใช้ Windows Defragmenter บนไดรฟ์ SAN หรือทีม SAN ควรใช้ยูทิลิตี้จัดเรียงข้อมูลภายในหรือไม่ การวิเคราะห์การแตกแฟรกเมนต์ที่ฉันได้รับจากเครื่องมือ Windows นั้นแม่นยำยิ่งขึ้นเมื่อทำงานบนไดรฟ์ SAN หรือไม่

  • การกระจายตัวทางกายภาพของ SQL มีขนาดใหญ่เพียงใด (ลองสมมติอาร์เรย์ไดรฟ์ภายในรอผลของคำถามก่อนหน้า) มันเป็นข้อตกลงที่ใหญ่กว่าการกระจายตัวของดัชนีภายในหรือไม่ หรือว่าเป็นปัญหาประเภทเดียวกันจริง ๆ(ไดรฟ์ต้องอ่านแบบสุ่มแทนการอ่านแบบลำดับ)

  • การจัดเรียงข้อมูล (หรือสร้างใหม่) ทำดัชนีเสียเวลาหากไดรฟ์มีการแยกส่วนทางร่างกายหรือไม่ ฉันต้องแก้ไขอันใดอันหนึ่งก่อนที่จะพูดกับอีกฝ่ายหรือไม่?

  • เป็นวิธีที่ดีที่สุดในการแก้ไขการกระจายตัวของไฟล์ทางกายภาพในกล่อง SQL ผลิตอะไร ฉันรู้ว่าฉันสามารถปิดบริการ SQL และเรียกใช้ Windows Defrag ได้ แต่ฉันยังได้ยินเกี่ยวกับเทคนิคที่คุณทำการสำรองข้อมูลเต็มรูปแบบวางฐานข้อมูลแล้วเรียกคืนจากการสำรองข้อมูลไปยังไดรฟ์ที่ว่างเปล่า แนะนำเทคนิคหลังนี้หรือไม่ ไม่เรียกคืนจากการสำรองข้อมูลเช่นนี้ยังสร้างดัชนีจากรอยขีดข่วนกำจัดการกระจายตัวของดัชนีภายใน? หรือเพียงแค่คืนคำสั่งซื้อหน้าเดียวกับเมื่อมีการสำรองข้อมูล? (เรากำลังใช้การสำรองข้อมูล Quest Lightspeed พร้อมการบีบอัดหากเป็นเช่นนั้น)

อัปเดต : คำตอบที่ดีจนถึงขณะนี้ว่าจะจัดระเบียบไดรฟ์ SAN (NO) และการจัดระเบียบดัชนียังคุ้มค่ากับไดรฟ์ที่มีการแยกส่วนทางกายภาพ (YES) หรือไม่

ใครสนใจที่จะชั่งน้ำหนักในวิธีที่ดีที่สุดสำหรับการจัดระเบียบข้อมูลจริง? หรือการประเมินระยะเวลาที่คุณคาดว่าจะต้องใช้ในการจัดเรียงข้อมูลไดรฟ์ที่มีการแยกส่วนขนาดใหญ่พูดว่า 500GB หรือมากกว่านั้น มีความเกี่ยวข้องอย่างเห็นได้ชัดเพราะถึงเวลาที่เซิร์ฟเวอร์ SQL ของฉันจะล่ม!

นอกจากนี้หากใครก็ตามมีข้อมูลประวัติย่อใด ๆ เกี่ยวกับการปรับปรุงประสิทธิภาพของ SQL ที่คุณทำโดยการแก้ไขการแตกแฟรกเมนต์แบบฟิสิคัลนั่นก็ยอดเยี่ยมเช่นกัน โพสต์บล็อกของ Mikeพูดถึงการเปิดเผยปัญหา แต่ไม่เฉพาะเจาะจงเกี่ยวกับการปรับปรุงที่ทำขึ้น

คำตอบ:


9

ฉันคิดว่าบทความนี้ให้ภาพรวมที่ยอดเยี่ยมของการจัดระเบียบของไดรฟ์ SAN

http://www.las-solanas.com/storage_virtualization/san_volume_defragmentation.php

จุดพื้นฐานคือการจัดเรียงข้อมูลไม่แนะนำให้ใช้กับที่เก็บข้อมูล SAN เนื่องจากเป็นการยากที่จะเชื่อมโยงตำแหน่งทางกายภาพของบล็อกบนดิสก์เมื่อตำแหน่งถูกทำให้เป็นเสมือนโดย SAN เมื่อแสดง LUN

หากคุณใช้การแมปอุปกรณ์ RAW หรือคุณมีการเข้าถึงชุด RAID โดยตรงที่เป็น LUN ที่คุณใช้งานอยู่ฉันสามารถเห็นการลดระดับเสียงมีผลในเชิงบวก แต่ถ้าคุณได้รับ LUN "เสมือน" จาก RAID ที่แชร์กัน 5 ชุดไม่มี


บทความที่ยอดเยี่ยม ตรงประเด็นเกี่ยวกับไดรฟ์ SAN
BradC

7

หลายส่วนของคำถามและคำตอบนี้:

การแตกไฟล์แบบฟิสิคัลไม่เกี่ยวข้องกับหน่วยเก็บข้อมูล Enterprise SAN อย่างแท้จริงเนื่องจาก Kevin ชี้ให้เห็นแล้ว - ดังนั้นจึงไม่มีอะไรเพิ่ม จริง ๆ แล้วลงไปที่ระบบย่อย I / O และคุณมีโอกาสที่จะทำให้ไดรฟ์เปลี่ยนไปจาก I / O ที่สุ่มมากขึ้นเมื่อทำการสแกนไปยัง I / O ตามลำดับที่มากขึ้นเมื่อทำการสแกน สำหรับ DAS เป็นไปได้ว่าคุณจะชอบ SAN slice-n-dice ที่ซับซ้อนมากขึ้นอาจไม่ใช่

การจัดเรียงข้อมูลระดับระบบไฟล์ - ทำได้เฉพาะเมื่อปิดระบบ SQL ฉันไม่เคยประสบปัญหากับตัวเองที่นี่ (เพราะฉันไม่เคยทำการออนไลน์, เปิดไฟล์ defrag ของไฟล์ฐานข้อมูล SQL) แต่ฉันได้ยินหลักฐานมากมายจากลูกค้าและลูกค้าของปัญหาการทุจริตแปลกที่เกิดขึ้น ภูมิปัญญาทั่วไปไม่ได้ทำกับ SQL ออนไลน์

การแตกแฟรกเมนต์ดัชนีนั้นเป็นฉากฉากที่สมบูรณ์สำหรับการแยกไฟล์ SQL Server ไม่มีความคิดเรื่องการแตกไฟล์ - เลเยอร์ virtualizatin มากเกินไปในระหว่างนั้นเพื่อให้มีความหวังในการทำงานกับรูปแบบระบบย่อย I / O จริง การกระจายตัวของดัชนีอย่างไรก็ตาม SQL รู้ทุกอย่างเกี่ยวกับ การแตกแฟรกเมนต์ดัชนีจะป้องกัน SQL ในการสแกนช่วงที่มีประสิทธิภาพไม่ว่าตัวเองมากเกินไปจากคำตอบที่คุณอ้างถึงไม่ว่าการแยกส่วน (หรือไม่) ไฟล์จะอยู่ในระดับระบบไฟล์อย่างไร ดังนั้น - คุณควรลดความกระจัดกระจายของดัชนีหากคุณเห็นประสิทธิภาพการค้นหาลดลง

คุณไม่จำเป็นต้องทำตามลำดับใด ๆ แม้ว่าคุณจะดูแลการแตกแฟรกเมนต์ของระบบไฟล์แล้วสร้างดัชนีทั้งหมดของคุณและทำให้การแตกแฟรกเมนต์ของระบบไฟล์เพิ่มขึ้น ถูก ticked off มันจะทำให้เกิดปัญหาใด ๆ perf หรือไม่ ตามที่กล่าวไว้ข้างต้นมันขึ้นอยู่กับ :-D

หวังว่านี่จะช่วยได้!


พึงรู้เถิดจริง ๆ แล้วการกระจายตัวของดัชนีภายในจะเปลี่ยนพฤติกรรมของเครื่องมือเพิ่มประสิทธิภาพหรือไม่เพื่อสนับสนุนการสแกนแบบเต็มแทนที่จะค้นหาช่วงดัชนีที่เหมาะสม
BradC

ไม่เครื่องมือเพิ่มประสิทธิภาพไม่มีความรู้ว่าข้อมูลถูกจัดเก็บไว้ในดิสก์อย่างไรนอกเหนือจากข้อเท็จจริงที่ว่ามีดัชนีอยู่ขนาดและสถิติการกระจายค่าคอลัมน์ เป็นเครื่องมือจัดเก็บข้อมูลที่ขับเคลื่อนหัวอ่านและปรับขนาด I / O แต่ละตัวตามการกระจายตัวของตรรกะในสิ่งที่สแกน
Paul Randal

3

เป็นวิธีที่ดีที่สุดในการแก้ไขการกระจายตัวของไฟล์ทางกายภาพในกล่อง SQL ผลิตอะไร

ฉันเรียกใช้ contig ของ SYSINTERNALS ในไฟล์ฐานข้อมูลของฉัน

ดูhttp://technet.microsoft.com/en-us/sysinternals/bb897428.aspx


ดูน่าสนใจ ฉันถือว่าเนื่องจากมันใช้ Windows defrag APIs, บริการ SQL นั้นจะต้องถูกปิด? หรือจะทำงานนี้ในขณะที่เซิร์ฟเวอร์ / ฐานข้อมูลออนไลน์?
BradC

ฉันใช้มันสำเร็จบนฐานข้อมูล MSSQL Server ออนไลน์ แต่เนื้อหาเหล่านั้นอยู่ในระดับต่ำการจราจรและฐานข้อมูลขนาดเล็ก (น้อยกว่า 10 กิกะไบต์)
วินเซนต์บั๊ก

นี่เป็นเครื่องมือที่ยอดเยี่ยม! ฉันคิดว่ามันเป็นแอพพลิเคชั่นสำหรับฐานข้อมูลที่ค่อนข้าง จำกัด ตามที่คนอื่นพูดถึง แต่ฉันชอบมันสำหรับไดรฟ์ประเภทอื่น โหมดการวิเคราะห์ -a นั้นปลอดภัยในขณะที่สิ่งต่าง ๆ กำลังทำงานอยู่ ฉันจะไม่รู้สึกปลอดภัยในการใช้งานกับไดรฟ์ที่เป็นของ SQL Server ที่ใช้งานอยู่
Kendra

2

ฉันขอแนะนำให้ปรับขนาดฐานข้อมูลอย่างเหมาะสมปิดเซิร์ฟเวอร์ sql ลงคัดลอกไฟล์ฐานข้อมูลไปยังอาร์เรย์ดิสก์อื่นแล้วคัดลอกกลับเพื่อจัดเรียงข้อมูล เร็วกว่าการใช้ windows Defrag ในประสบการณ์ของฉัน


1

ฉันพยายามจัดเรียงข้อมูลดิสก์ทางกายภาพในโซลูชัน scsi หนึ่งครั้ง แต่เพิ่มประสิทธิภาพเพียงเล็กน้อยหรือไม่มีเลย บทเรียนที่ฉันได้เรียนรู้คือถ้าคุณประสบกับประสิทธิภาพการทำงานช้าเนื่องจากระบบดิสก์มันไม่มีอะไรเกี่ยวข้องกับการแตกแฟรกเมนต์เท่าที่เราพูดถึงไฟล์ข้อมูลเนื่องจากมันใช้การเข้าถึงแบบสุ่ม

หากดัชนีของคุณมีการจัดเรียงข้อมูลและสถิติมีการปรับปรุง (สำคัญมาก) และคุณยังคงเห็น I / O เป็นคอขวดคุณก็จะต้องทนทุกข์ทรมานจากสิ่งอื่นนอกเหนือจากการแยกส่วนทางกายภาพ คุณใช้ไดรฟ์มากกว่า 80% แล้วหรือยัง คุณมีไดรฟ์เพียงพอหรือไม่ ข้อความค้นหาของคุณได้รับการปรับให้เหมาะสมเพียงพอหรือไม่ คุณกำลังทำการสแกนตารางจำนวนมากหรือทำดัชนีให้ค้นหาแย่ลงตามด้วยการค้นหาดัชนีแบบกลุ่มหรือไม่? ดูที่แผนคิวรีและใช้ "ตั้งค่าสถิติ io บน" เพื่อค้นหาว่าเกิดอะไรขึ้นกับข้อความค้นหาของคุณ (มองหาการอ่านเชิงตรรกะหรือทางกายภาพจำนวนมาก)

โปรดแจ้งให้เราทราบหากฉันผิดอย่างสมบูรณ์

/ Håkan Winther


ไม่คุณไม่ผิด แต่พยายามที่จะทำให้การปรับปรุงเซิร์ฟเวอร์ทั้งบาง (ถ้าเป็นไปได้) เป็นบิตที่น่าสนใจมากขึ้นกว่าการเริ่มต้นที่จะดำน้ำในงบ 150,000 SQL แตกต่างกันที่การดำเนินการในช่วงงานวิเคราะห์รายสัปดาห์ (ไม่ได้พูดเกินจริงอาจจะพูดจริง.)
BradC

หากคุณมีสถานการณ์แบบนั้นฉันขอแนะนำ Veritas I3 เพื่อวิเคราะห์สภาพแวดล้อมของคุณเพื่อดูว่าคุณกำลังทุกข์ทรมานจากปัญหาคอขวดและอะไรที่ทำให้เกิดคอขวด Veritas I3 ติดตามข้อความทั้งหมดและความถี่ที่ถูกเรียกและราคาเท่าไร มันเป็นซอฟต์แวร์ที่ยอดเยี่ยม
Hakan Winther

1

บางทีดัชนีอาจไม่ได้รับการปรับให้เหมาะสมเพียงพอสำหรับแอปพลิเคชันของคุณและคุณไม่มี Veritas I3 เพื่อปรับฐานข้อมูลของคุณให้เหมาะสมจากนั้นคุณสามารถใช้คำสั่งเช่นนี้เพื่อค้นหาดัชนีที่ขาดหายไป:

       SELECT
      mid.statement,
      mid.equality_columns,
      mid.inequality_columns,
      mid.included_columns,
      migs.user_seeks,
      migs.user_scans,
      migs.last_user_seek,
      migs.avg_user_impact,
      user_scans,
      avg_total_user_cost,
      avg_total_user_cost * avg_user_impact * (user_seeks + user_scans) AS [weight]--, migs.*--, mid.*
   FROM
      sys.dm_db_missing_index_group_stats AS migs
      INNER JOIN sys.dm_db_missing_index_groups AS mig
         ON (migs.group_handle = mig.index_group_handle)
      INNER JOIN sys.dm_db_missing_index_details AS mid
         ON (mig.index_handle = mid.index_handle)
   ORDER BY
      avg_total_user_cost * avg_user_impact * (user_seeks + user_scans) DESC ;

หรือคำสั่งเช่นนี้เพื่อค้นหาดัชนีที่ไม่ได้ใช้ในคำสั่งที่เลือกและลดประสิทธิภาพการอัพเดต / การแทรก:

    CREATE PROCEDURE [ADMIN].[spIndexCostBenefit]
    @dbname [nvarchar](75)
WITH EXECUTE AS CALLER
AS
--set @dbname='Chess'
declare @dbid nvarchar(5)
declare @sql nvarchar(2000)
select @dbid = convert(nvarchar(5),db_id(@dbname))

set @sql=N'select ''object'' = t.name,i.name
        ,''user reads'' = iu.user_seeks + iu.user_scans + iu.user_lookups
        ,''system reads'' = iu.system_seeks + iu.system_scans + iu.system_lookups
        ,''user writes'' = iu.user_updates
        ,''system writes'' = iu.system_updates
from '+ @dbname + '.sys.dm_db_index_usage_stats iu
,' + @dbname + '.sys.indexes i
,' + @dbname + '.sys.tables t
where 
    iu.database_id = ' + @dbid + '
and iu.index_id=i.index_id
and iu.object_id=i.object_id
and iu.object_id=t.object_id
AND (iu.user_seeks + iu.user_scans + iu.user_lookups)<iu.user_updates
order by ''user reads'' desc'

exec sp_executesql @sql

set @sql=N'SELECT
   ''object'' = t.name,
   o.index_id,
   ''usage_reads'' = user_seeks + user_scans + user_lookups,
   ''operational_reads'' = range_scan_count + singleton_lookup_count,
   range_scan_count,
   singleton_lookup_count,
   ''usage writes'' = user_updates,
   ''operational_leaf_writes'' = leaf_insert_count + leaf_update_count + leaf_delete_count,
   leaf_insert_count,
   leaf_update_count,
   leaf_delete_count,
   ''operational_leaf_page_splits'' = leaf_allocation_count,
   ''operational_nonleaf_writes'' = nonleaf_insert_count + nonleaf_update_count + nonleaf_delete_count,
   ''operational_nonleaf_page_splits'' = nonleaf_allocation_count
FROM
   ' + @dbname + '.sys.dm_db_index_operational_stats(' + @dbid + ', NULL, NULL, NULL) o,
   ' + @dbname + '.sys.dm_db_index_usage_stats u,
    ' + @dbname + '.sys.tables t
WHERE
   u.object_id = o.object_id
   AND u.index_id = o.index_id
    and u.object_id=t.object_id
ORDER BY
   operational_reads DESC,
   operational_leaf_writes,
   operational_nonleaf_writes'

exec sp_executesql @sql

GO

ฉันมีคำสั่ง SQL อื่น ๆ ที่ฉันใช้เมื่อฉันวิเคราะห์ปัญหาประสิทธิภาพการทำงานในสภาพแวดล้อมการผลิต แต่ทั้งสองนี้เป็นการเริ่มต้นที่ดีที่ฉันคิด

(ฉันรู้ว่าโพสต์นี้เป็นหัวข้อเล็กน้อย แต่ฉันคิดว่าคุณอาจสนใจเพราะเกี่ยวข้องกับกลยุทธ์การจัดทำดัชนี)

/ Håkan Winther


สคริปต์ที่ยอดเยี่ยมฉันมีบางอย่างที่คล้ายกันมาก น่าเสียดายที่เรายังคงมี 40% ของ SQL 2000 (รวมถึงเซิร์ฟเวอร์ที่มีปัญหา) ซึ่งไม่เทียบเท่ากับ DMV "ดัชนีที่ขาดหาย" เหล่านี้
BradC

ฉันเห็นแล้วฉันแนะนำให้คุณดูที่ Veritas I3 มันเป็นผลิตภัณฑ์ที่ยอดเยี่ยมที่คุณสามารถใช้ปรับแต่งฐานข้อมูลของคุณ แต่ไม่ใช่ซอฟต์แวร์ราคาถูก
Hakan Winther
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.