SQL数据库物理文件碎片


19

我知道有真正的三个种类的碎片,我需要被关心的DBA:

  1. SQL数据文件中的索引碎片,包括聚集的索引(表)碎片。使用DBCC SHOWCONTIG(在SQL 2000中)或sys.dm_ db_ index_ physical_ stats(在2005+中)进行识别。

  2. SQL日志文件中的VLF碎片。运行DBCC LOGINFO以查看每个SQL日志文件中有多少个VLF。

  3. 硬盘驱动器上数据库文件的物理文件碎片。通过使用Windows中的“磁盘碎片整理程序”实用程序进行诊断。(受到这篇出色的博客文章的启发)

索引碎片引起了很多关注(请参阅Paul Randall的Serverfault出色回答),因此这不是我的问题的重点。

我知道当最初通过计划合理的预期数据文件和日志大小来创建数据库时,可以防止物理碎片(和VLF碎片),因为这种碎片通常发生在频繁的增长和收缩中,但是我有一些有关如何解决的问题物理碎片一旦被识别:

  • 首先,物理碎片是否在企业级SAN上也相关?是否可以在SAN驱动器上使用Windows Defragmenter,或者SAN团队应使用内部碎片整理实用程序?在SAN驱动器上运行时,我从Windows工具获得的碎片分析结果是否准确

  • 物理碎片对SQL性能的影响有多大?(让我们假设一个内部驱动器阵列,等待上一个问题的结果。)这比内部索引碎片还大吗?还是真的是同一类型的问题(驱动器必须执行随机读取而不是顺序读取)

  • 如果驱动器物理碎片化,则对碎片整理(或重建)索引是否浪费时间?我需要先解决一个问题吗?

  • 在生产SQL框中修复物理文件碎片的最佳方法是什么?我知道我可以关闭SQL服务并运行Windows Defrag,但是我也听说过一种技术,您可以进行完全备份,删除数据库,然后从备份还原到空驱动器。是否推荐使用后一种技术?从这样的备份还原是否还会从头开始建立索引,从而消除内部索引碎片?还是只是简单地将页面顺序恢复为执行备份时的页面顺序?(如果需要的话,我们正在使用具有压缩功能的Quest Lightspeed备份。)

更新:关于是否对SAN驱动器进行碎片整理(否),以及在物理碎片驱动器上是否仍然值得进行索引碎片整理(是),到目前为止,已经有了很好的答案。

还有其他人愿意权衡实际进行碎片整理的最佳方法吗?还是对碎片整理大型碎片驱动器(例如500GB左右)所需的时间估计?显然相关,因为那是我的SQL Server停机的时候!

另外,如果任何人都拥有通过修复物理碎片而获得的有关SQL性能改进的轶事,那也很好。Mike的博客文章讨论了发现问题的方法,但并没有具体说明它做了什么样的改进。

Answers:


9

我认为本文很好地概述了SAN驱动器的碎片整理

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

基本要点是,不建议在SAN存储上进行碎片整理,因为当提供LUN时,SAN已虚拟化了磁盘上块的物理位置,因此很难关联该块的物理位置。

如果您使用的是RAW设备映射,或者可以直接访问作为您正在使用的LUN的RAID集,那么碎片整理会产生积极的效果,但是如果您从共享RAID中获得了“虚拟” LUN, 5套,没有。


优秀的文章。就SAN驱动器而言,就是正确的选择。
BradC

7

此问题和答案的多个部分:

就像Kevin已经指出的那样,物理文件碎片与Enterprise SAN存储并没有真正的关系-因此没有什么可添加的。这确实取决于I / O子系统,以及使驱动器从执行扫描时的更多随机I / O变为执行扫描时的更多顺序I / O的可能性。对于DAS,对于复杂的slice-n-dice SAN,您更有可能不会。

文件系统级别的碎片整理-仅在SQL关闭时进行。我自己从来没有遇到过问题(因为我从未执行过在线,开放文件的SQL数据库文件碎片整理),但是我从客户那里听到许多轶事证据,证明正在发生奇怪的损坏问题。一般的智慧是不要在线使用SQL。

索引碎片与文件碎片完全正交。SQL Server没有文件碎片整理的想法,因为它们之间的虚拟化层太多,因此没有希望计算出实际的I / O子系统几何形状。索引碎片,但是,SQL确实了解一切。不必对您已经引用的答案重复太多,索引碎片将阻止SQL进行有效的范围扫描预读,而不管文件在文件系统级别上的碎片情况如何。所以-如果您发现查询性能下降,则绝对应该减轻索引碎片的影响。

你不会任何特定的顺序做这些,但如果你照顾文件系统碎片,然后重新生成所有的指标,并通过磁盘碎片整理卷上成长多个文件会导致更多的文件系统碎片,你很可能会被打勾。但是会引起性能问题吗?如上所述,这取决于:-D

希望这可以帮助!


嗯,那么内部索引碎片实际上会改变优化器的行为,而偏向全扫描而不是适当的索引范围搜索吗?
BradC

否。除了索引存在,索引的大小和列值分布统计信息这一事实外,优化器还不知道如何将数据存储在磁盘上。是存储引擎驱动预读并根据其扫描内容的逻辑碎片来更改各个I / O大小。
Paul Randal

3

在生产SQL框中修复物理文件碎片的最佳方法是什么?

我在数据库文件上运行SYSINTERNALS的contig。

请参阅http://technet.microsoft.com/en-us/sysinternals/bb897428.aspx


看起来很有趣。我假设由于它使用Windows碎片整理API,因此必须关闭SQL服务吗?还是在服务器/数据库联机时运行?
BradC

我已经在联机MSSQL Server数据库上成功使用了它。但是可以说那些是低流量的小型数据库(小于10Gb)
Vincent Buck 2009年

这是一个很棒的工具!我认为它的数据库应用程序非常有限,正如其他人所提到的那样,但我喜欢其他类型的驱动器。运行时,分析模式-a是安全的。但是,对于在属于实时SQL Server的驱动器上运行它,我感到不安全。
肯德拉2009年

2

我建议适当调整数据库的大小,关闭sql server,将数据库文件复制到另一个磁盘阵列,然后再复制回去进行碎片整理。根据我的经验,它比使用Windows碎片整理快得多。


1

我曾尝试对scsi解决方案中的物理磁盘进行碎片整理,但性能几乎没有提升。我吸取的教训是,如果由于磁盘系统而导致性能降低,那么就我们所说的数据文件而言,它与碎片无关,因为它使用的是随机访问。

如果对索引进行碎片整理并且更新统计信息(非常重要),并且您仍然将I / O视为瓶颈,那么除物理碎片之外,您还会遭受其他麻烦。您是否已使用超过80%的驱动器?您有足够的驱动器吗?您的查询是否足够优化?您是否要进行大量的表扫描,或者更糟糕的是要进行大量索引查找,然后进行聚集索引查找?查看查询计划,并使用“设置统计信息”,以了解查询的实际情况。(寻找大量逻辑或物理读取)

如果我完全错了,请告诉我。

/霍坎·温瑟(HåkanWinther)


不,你没错。但是,尝试在服务器范围内进行一些改进(如果可能的话)比开始研究在每周分析工作中执行的150,000多个不同的SQL语句更具吸引力(实际上并不是夸张。实际上可能是轻描淡写)
BradC

如果您遇到这种情况,我建议您使用Veritas I3来分析您的环境,以了解您正在遭受的瓶颈以及造成瓶颈的原因。Veritas I3会跟踪所有语句以及它们被调用的频率以及费用。这是一个出色的软件。
哈坎·温瑟

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 ;

或类似这样的语句来查找未在select语句中使用的索引并降低了更新/插入性能:

    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åkanWinther)


优秀的脚本,我有一些非常相似的东西。不幸的是,我们仍然使用40%的SQL 2000(包括所讨论的服务器),它与这些“缺失索引” DMV没有任何等效关系。
2009年

我知道了,然后我建议您看看Veritas I3。它是一款出色的产品,可用于调整数据库,但它并非廉价软件。
哈坎·温瑟
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.