Ha-私が尋ねられる(嫌いな)お気に入りの質問(DBCC CHECKDBを書いたとき)。
どうぞ:
CHECKDBにかかる時間を計算する必要があるのは、定期的なデータベースのメンテナンスを計画しているときだけです。データベースの破損(または破損の疑い)に直面していて、CHECKDBにかかる時間について考え始めたばかりの場合は、ディザスタリカバリ戦略の計画中に間違いを犯しました。データベースに対してCHECKDBを実行するのに(平均で)かかる時間を常に知る必要があるため、次のようになります。
- CHECKDBの特定の実行に通常よりも時間がかかっているかどうかを確認できます。これは、破損が見つかったことを示しています。
- 災害復旧の状況で結果を得るのにどれくらいの時間がかかるか知っています
私が行くすべての会議で、誰かがCHECKDBをデータベースで実行するのにどれくらいの時間がかかるかを私に尋ねます。私がこれに答えることができるいくつかの方法があります:
- 役に立たない答え-私にはわかりません。
- ほぼ役立つ答え-前回の実行にはどれくらいの時間がかかりましたか?条件はまったく同じですか?
- 私が通常与える答え-それは異なります。
さて、多くの人は、3番目の答えが最初の答えと幾分同等であると見なすでしょう-役に立たない。問題は、CHECKDBの実行にかかる時間に影響を与える多くの要因があることです。これが実際に役立つ答えである理由がわかるように、最も重要な10の要素について説明します。これらは特に重要な順序ではありません。
- データベースのサイズかなり明白です... CHECKDBはデータベース内の割り当てられたすべてのページを読み取る必要があるため、サイズが大きいほど、すべてのページを読み取るのに時間がかかります。
- サーバーでの同時IOロード最も単純なレベルでは、CHECKDBは何をしますか?データベース内の割り当てられたすべてのページを読み取ります。それは多くのIOです。 CHECKDBは、可能な限り最も効率的なIOを実行し、データベースページを物理的な順序で読み取り、ディスクヘッドがディスク間をスムーズに移動するように(ランダムにジャンプしてディスクに負担をかけるのではなく)、多大な労力を費やします。ヘッドシークの遅延)。サーバーに同時のIO負荷がない場合、IOはCHECKDBが作成できるのと同じくらい効率的です。ただし、SQLServerから追加のIOを導入すると、ディスクヘッドがジャンプし、CHECKDBIOの速度が低下します。 IOサブシステムがすでにCHECKDBのIO要求からの容量にある場合、追加のIOは、CHECKDBで使用可能なIO帯域幅を削減します。 -速度を落とします。
- サーバーでの同時CPUアクティビティ次のレベルの単純さでは、CHECKDBは読み取るすべてのページを何らかの方法で処理します。指定したさまざまなオプションとデータベーススキーマ(詳細は以下)によっては、多くのCPUを使用することになります。CHECKDBの実行中にサーバーが100%CPUに固定される可能性があります。サーバーに追加のワークロードがある場合、それはCHECKDBからCPUサイクルを奪い、それを遅くします。基本的に、ポイント#2と#3が言っているのは、CHECKDBは非常にリソースを消費するということです。これはおそらくSQLServerに依頼できる最もリソースを消費することのひとつであり、通常、ワークロードのピーク時に実行しないことをお勧めします。これは、CHECKDBの実行に時間がかかるだけでなく、速度が低下するためです。同時ワークロード、おそらく許容できない。
- データベースでの同時更新アクティビティこれはSQL2000とSQL2005の両方に関連しますが、理由は異なります。 SQL 2000では、CHECKDBは、同時DMLトランザクションのトランザクションログ分析からデータベースの一貫したビューを取得します(詳細については、ここを参照してください)。 CHECKDBの実行中に同時に発生するDMLが多いほど、生成されるトランザクションログが多くなるため、CHECKDBがそのトランザクションログを分析するのにかかる時間が長くなります。大量の同時DMLとCHECKDBが単一のCPUに制限されている大規模なマルチCPUボックスでは、CHECKDBのこのフェーズがデータベースページの読み取りと処理よりも数倍長くかかる可能性があります。 (これは実際に何度か見ました。)SQL 2005では、CHECKDBは、データベース自体と同じディスクボリュームに格納されているデータベーススナップショットからデータベースの一貫したビューを取得します。 CHECKDBの実行中にデータベースに多くの変更があった場合、変更されたページはスナップショットにプッシュされ、一貫性が保たれます。スナップショットファイルはデータベースファイルと同じ場所に保存されるため、ページがスナップショットにプッシュされるたびに、ディスクヘッドを移動する必要があります。これにより、#2で説明した効率的なIOが中断されます。また、CHECKDBがページを読み取りに行き、データベースファイルではなくスナップショットファイルからページを読み取る必要がある場合は常に、それは別のディスクヘッドの移動であり、別の効率的なIO中断です。データベースへの同時変更が多いほど、効率的なIOの中断が多くなり、CHECKDBの実行が遅くなります。
- IOサブシステムのスループット機能これは単純です。 CHECKDBはIOのボートロードを実行し、指定されたオプションとデータベーススキーマによっては、IOバウンドになる可能性があります(つまり、CPUはIOが完了するのを定期的に待機します)。これは、IOサブシステムのスループットがCHECKDBのランタイムに直接影響することを意味します。したがって、1TBのデータベースがあり、IOサブシステムが100MB /秒しか管理できない場合、データベースを読み取るだけで約3時間かかり(1TB/100MB/3600秒)、何もできません。 IOサブシステムをアップグレードすることを除いて、それをスピードアップするために行います。 CHECKDB(またはインデックスの再構築やその他のIOを多用する操作)の実行速度が遅いと顧客から苦情が寄せられ、ディスクキューの長さが非常に長く、IOであることがわかった回数は、数え切れません。 _サブシステムそれはサーバーとワークロードに完全に匹敵しません。
- ボックス上のCPU(プロセッシングコア)の数これには、実行されているSQLServerのエディションも含まれます。 Enterprise Editionでは、CHECKDBはボックス内のすべてのCPU間で並列に実行できます(または、CHECKDB内部クエリがコンパイルされるときにクエリプロセッサが並列化することを決定した数だけ)。並列で実行すると、データベースが複数のファイルにも分散している限り、CHECKDBのパフォーマンスが大幅に向上し、実行時間が短縮されます(IOを並列化できます)。 CHECKDBを並行して実行できるようにする、気の利いたアルゴリズムが使用されています。これについては、今後の投稿で詳しく説明します。一方、Enterprise EditionでCHECKDBを並行して実行できるという事実は、シナリオによっては悪い場合があるため、一部のDBAは、CHECKDBを強制的にシングルスレッドにすることを選択しました。 SAPは通常、ユーザークエリの予測可能性を高めるためにこれを推奨しています。これを行う方法は、文書化されたトレースフラグ2528をオンにすることです。
- tempdbが配置されているディスクの速度 VLDBに対してCHECKDBを実行すると、内部状態に大量のメモリが使用され、VLDBの場合、メモリ要件は通常、SQLServerで使用可能なメモリの量を超えます。この場合、状態はtempdbにスプールアウトされるため、tempdbのパフォーマンスがCHECKDBのパフォーマンスの重要な要素になる可能性があります。この詳細と、tempdbが小さすぎる場合にCHECKDBがディスク領域を使い果たす方法については、この投稿を参照してください。
- データベーススキーマの複雑さこれは、CHECKDBが必要とするCPUの量に影響を与えるため、CHECKDBの実行時に非常に大きな影響を与える可能性があります。たとえば、CHECKDBが実行する最もコストのかかるチェックは、非クラスター化インデックスに対するものです。非クラスター化インデックスの各行が、テーブルのヒープまたはクラスター化インデックスの1つの行に正確にマップされていること、およびすべてのヒープ/クラスター化インデックスの行に、各非クラスター化インデックスの一致する行が1つだけあることを確認する必要があります。これを行うための非常に効率的なアルゴリズムがありますが、それでもCHECKDBが使用する合計CPUの約30%を使用します。機能がデータベースで使用されている場合にのみ実行される他のチェックがたくさんあります-例:計算された列の評価、行外のLOB値間のリンク、Service Broker、XMLインデックス、インデックス付きビュー-したがって、実行時を決定するには、経験的な要因だけでは不十分であることがわかります。
- どのオプションが指定されているかこれは、さまざまなオプションを指定することにより、CHECKDBが実際に実行するチェックを制限するという点で#7とほぼ同じです。たとえば、WITH NOINDEXオプションを使用すると、#7で説明した非クラスター化インデックスチェックがオフになり、WITH PHYSICAL_ONLYオプションを使用すると、すべての論理チェックがオフになり、CHECKDBの実行時間が大幅に短縮され、ほぼ常にIOになります。 -CPUバウンドではなくバウンド(実際、これはVLDBのDBAがCHECKDBのランタイムを管理可能にするために使用する最も一般的なオプションです)。注意すべき点の1つは、修復オプションを指定すると、Enterprise Editionのマルチプロシージャボックスでも、CHECKDBは常にシングルスレッドで実行されます。
- データベースに存在する破損の数と種類繰り返しますが、これは#7と#8に似ています。破損が存在する場合は、破損の詳細を把握するために追加のチェックがトリガーされる場合があります。たとえば、非クラスター化インデックスチェックの場合、破損が存在しない場合(世界中でCHECKDBが毎日何百万回も実行されていることを考えると、圧倒的多数のケース)に合わせてアルゴリズムが非常に大幅に調整されています。非クラスター化インデックスの破損が検出された場合、破損がどこにあるかを正確に把握するために、より詳細なアルゴリズムを使用する必要があります。これには、大量のデータを再スキャンするため、大量の時間がかかります。このような他のアルゴリズムもいくつかあります。
ここでもう1つ覚えておくべきことは、REPAIR_ALLOW_DATA_LOSSを使用すると、チェックがシングルスレッドで実行されるため、修復が正しく順序付けられるため、実行時間が長くなることです。 2005 SP2 +のエラーログでメッセージ5268を確認してください。これは、前述のように、詳細を示しています。
要約つまり、簡単な答えはないことがわかります。お役に立てれば!
PS SQL 2005で、進捗レポートをDBCCCHECKDBに追加したことを忘れました。 sys.dm_exec_requests
DMVにクエリを実行し、percent_complete
列を探すことができます。