SQLデータベースの物理ファイルの断片化


19

DBAとして心配する必要がある断片化には、実際には3種類あることを知っています。

  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デフラグツールを使用できますか、またはSANチームが内部デフラグユーティリティを使用する必要がありますか?SAN ツールで実行した場合、Windowsツールから取得した断片化分析は正確ですか?

  • SQLパフォーマンスの物理的な断片化はどれほど大きな問題ですか?(前の質問の結果が出るまで、内部ドライブアレイを想定しましょう。)内部インデックスの断片化よりも大したことですか?または、それは本当に同じ種類の問題ですか(ドライブは順次読み取りの代わりにランダム読み取りを行う必要があります)

  • ドライブが物理的に断片化されている場合、インデックスの最適化(または再構築)は時間の無駄ですか?もう一方に対処する前に、一方を修正する必要がありますか?

  • 運用SQLボックスで物理ファイルの断片化を修正する最良の方法は何ですか?SQLサービスをオフにしてWindows Defragを実行できることは知っていますが、完全バックアップを実行し、データベースを削除してから、バックアップから空のドライブに復元する手法についても聞きました。この後者の手法は推奨されますか?このようなバックアップから復元んまた、内部インデックスの断片化を解消する、ゼロからインデックスを構築しますか?または、バックアップが行われたときと同じページ順序を単に返すだけですか?(問題があれば、Quest Lightspeedの圧縮バックアップを使用しています。)

更新:これまでのところ、SANドライブを最適化するか(NO)、物理的に断片化されたドライブでインデックスの最適化を行う価値があるか(YES)については良い回答があります。

最適化を実際に行うための最良の方法を検討したい人はいますか?または、500GB程度の大きな断片化されたドライブを最適化するのにかかると予想される時間の長さの推定値は?明らかに、これは私のサーバーがダウンする時間だからです!

また、物理的な断片化を修正することでSQLパフォーマンスが向上したという逸話的な情報があれば、それも素晴らしいことです。Mikeのブログ投稿では、問題の発見について説明していますが、どのような改善が行われたかについては明確ではありません。

回答:


9

この記事はSANドライブの最適化の優れた概要を提供すると思います

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

基本的なポイントは、LUNを提示するときにSANによって場所が仮想化されている場合、ディスク上のブロックの物理的な場所を関連付けることが難しいため、SANストレージでの最適化は推奨されないことです。

RAWデバイスマッピングを使用していた場合、または作業中のLUNであるRAIDセットに直接アクセスできる場合、デフラグメンテーションがプラスの効果を発揮することがありますが、共有RAIDから「仮想」LUNが与えられた場合、 5セット、いいえ。


素晴らしい記事。SANドライブに関しては、まさにその通りです。
BradC 2009年

7

この質問と回答の複数の部分:

Kevinが既に指摘したように、物理ファイルの断片化はEnterprise SANストレージにはあまり関係ありません。それは本当にI / Oサブシステムにかかっており、スキャンを実行するときのドライブをよりランダムなI / Oから、スキャンを実行するときのより多くのシーケンシャルI / Oに変えることができる可能性がどれほどあります。DASの場合、複雑なスライスアンドダイスSANの場合、おそらくそうではないでしょう。

ファイルシステムレベルのデフラグ-SQLシャットダウンでのみ実行します。ここで自分自身で問題を経験したことはありません(SQLデータベースファイルのオンラインでオープンファイルのデフラグを実行したことがないため)が、奇妙な破損問題が発生しているという顧客およびクライアントからの多くの事例証拠を聞きました。一般的な知恵は、SQLオンラインでそれを行うことではありません。

インデックスの断片化は、ファイルの断片化と完全に直交しています。SQL Serverには、ファイルの断片化の概念がありません。実際のI / Oサブシステムのジオメトリをうまく処理することを期待するには、あまりにも多くの仮想化レイヤーがあります。ただし、インデックスの断片化については、SQLはすべてを知っています。既に参照した回答から繰り返しすぎずに、インデックスの断片化により、ファイルシステムレベルでのファイルの断片化の有無にかかわらず、SQLは効率的な範囲スキャン先読みを実行できなくなります。そのため、クエリのパフォーマンスが低下している場合は、絶対にインデックスの断片化を軽減する必要があります。

これらを特定の順序で実行する必要はありません、ファイルシステムの断片化を処理してからすべてのインデックスを再構築し、最適化されたボリューム上で複数のファイルを成長させることによりファイルシステムの断片化を引き起こす場合は、おそらくオフになります。ただし、パフォーマンスの問題は発生しますか?上記のように、それは依存します:-D

お役に立てれば!


ああ、内部インデックスの断片化はオプティマイザーの動作を実際に変更して、適切なインデックス範囲のシークではなく完全スキャンを優先しますか?
BradC 2009年

いいえ。オプティマイザは、インデックスが存在するという事実、そのサイズ、および列値の分布統計を除き、データがディスクにどのように格納されているかを知りません。先読みを駆動し、スキャン対象の論理的な断片化に基づいて個々のI / Oサイズを変更するのは、ストレージエンジンです。
ポールランダル

3

運用SQLボックスで物理ファイルの断片化を修正する最良の方法は何ですか?

データベースファイルに対してSYSINTERNALSのコンティグを実行します。

http://technet.microsoft.com/en-us/sysinternals/bb897428.aspxを参照してください


面白そうです。WindowsデフラグAPIを使用しているため、SQLサービスをオフにする必要があると思いますか?または、サーバー/データベースがオンラインのときにこれを実行しますか?
BradC 2009年

オンラインMSSQL Serverデータベースで正常に使用しました。しかし、間違いなく、これらは、低トラフィックや小規模なデータベース(10Gbの未満)だった
ヴィンセント・バック

これは素晴らしいツールです!他の人が言ったように、データベース用のアプリケーションはかなり限られていると思いますが、他のタイプのドライブには気に入っています。分析モード-aは、実行中は安全です。ただし、ライブSQL Serverに属するドライブに対して実行しても安全ではありません。
ケンドラ

2

データベースのサイズを適切に調整し、SQLサーバーをシャットダウンし、データベースファイルを別のディスクアレイにコピーし、それをコピーしてデフラグします。私の経験では、Windowsデフラグを使用するよりもはるかに高速です。


1

scsiソリューションで物理ディスクのデフラグを1回試みましたが、パフォーマンスはほとんどまたはまったく向上しませんでした。私が学んだ教訓は、ディスクシステムが原因でパフォーマンスが低下した場合、ランダムアクセスを使用しているため、データファイルについて言えば、断片化とは関係がないということです。

インデックスが最適化されており、統計が更新されている(非常に重要)場合でも、I / Oがボトルネックとして表示される場合、物理的な断片化以外の問題が発生しています。ドライブの80%以上を使用しましたか?十分なドライブがありますか?クエリは十分に最適化されていますか?多くのテーブルスキャンを実行していますか、さらに悪いことに、多くのインデックスシークとクラスター化インデックスルックアップを実行していますか?クエリプランを確認し、「set statistics io on」を使用して、クエリで実際に何が起こっているかを調べます。(多数の論理読み取りまたは物理読み取りを探します)

私が完全に間違っているかどうかを教えてください。

/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ステートメントがいくつかありますが、これら2つは良いスタートだと思います。

(この投稿はちょっとしたトピックですが、インデックス作成戦略に関係しているので、興味があるかもしれないと思いました)

/HåkanWinther


優れたスクリプト、私はいくつか非常に似ています。残念ながら、私たちはまだ40%SQL 2000(問題のサーバーを含む)であり、これらの「インデックスが欠落している」DMVに相当するものはありません。
BradC 2009年

そうですね、Veritas I3をご覧になることをお勧めします。データベースの調整に使用できる優れた製品ですが、安価なソフトウェアではありません。
ハカンウィンサー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.