sql >> データベース >  >> RDS >> Database

ニージャーク待機統計:PAGEIOLATCH_SH

    今年の私の投稿では、さまざまな待機タイプに対するひざまずく反応について説明してきました。この投稿では、待機統計のテーマを続けて、PAGEIOLATCH_XXについて説明します。 待つ。 「待つ」と言いますが、実際には複数の種類のPAGEIOLATCHがあります 待っています、これは最後にXXで示しています。最も一般的な例は次のとおりです。

    • PAGEIOLATCH_SH –( SH are)データファイルページがディスクからバッファプールに取り込まれ、その内容を読み取れるようになるのを待っています
    • PAGEIOLATCH_EX またはPAGEIOLATCH_UP –( EX 包括的またはUP 日付)データファイルページがディスクからバッファプールに取り込まれ、その内容を変更できるようになるのを待っています

    これらのうち、最も一般的なタイプはPAGEIOLATCH_SHです。 。

    この待機タイプがサーバーで最も一般的である場合、ひざまずく反応は、I / Oサブシステムに問題がある必要があるため、調査に焦点を当てる必要があるということです。

    最初に行うことは、PAGEIOLATCH_SHを比較することです ベースラインに対する待機回数と期間。待機の量がほぼ同じであるが、各読み取り待機の期間がはるかに長くなっている場合は、次のようなI/Oサブシステムの問題が心配になります。

    • I/Oサブシステムレベルでの設定ミス/誤動作
    • ネットワーク遅延
    • ワークロードとの競合を引き起こす別のI/Oワークロード
    • 同期I/Oサブシステムレプリケーション/ミラーリングの構成

    私の経験では、パターンは多くの場合、PAGEIOLATCH_SHの数です。 多数の読み取りがI/Oサブシステムに過負荷をかけるため、待機はベースライン(通常)量から大幅に増加し、待機時間も増加しました(つまり、読み取りI / Oの時間が増加しました)。これはI/Oサブシステムの問題ではありません。これは、SQLServerが本来よりも多くのI/Oを駆動しているためです。ここで、フォーカスをSQL Serverに切り替えて、余分なI/Oの原因を特定する必要があります。

    多数の読み取りI/Oの原因

    SQL Serverには、論理I/Oと物理I/Oの2種類の読み取りがあります。ストレージエンジンのアクセスメソッド部分がページにアクセスする必要がある場合、メモリ内のページへのポインタ(論理I / Oと呼ばれる)をバッファプールに要求し、バッファプールはそのメタデータをチェックしてそのページがすでにメモリにあります。

    ページがメモリ内にある場合、バッファプールはアクセスメソッドにポインタを与え、I/Oは論理I/Oのままです。ページがメモリにない場合、バッファプールは「実際の」I / O(物理I / Oと呼ばれる)を発行し、スレッドはページが完了するのを待つ必要があります– PAGEIOLATCH_XX 待つ。 I / Oが完了し、ポインターが使用可能になると、スレッドに通知され、実行を続行できます。

    理想的な世界では、ワークロード全体がメモリに収まるため、バッファプールが「ウォームアップ」されてすべてのワークロードを保持すると、それ以上の読み取りは不要で、更新されたデータの書き込みのみが必要になります。しかし、それは理想的な世界ではなく、ほとんどの人はそのような贅沢を持っていないので、いくつかの読み取りは避けられません。読み取り数がベースライン量の前後にある限り、問題はありません。

    突然、予期せずに大量の読み取りが必要になった場合は、ワークロード、ページのメモリ内コピーを保存するために使用できるバッファプールメモリの量、またはその両方に大きな変化があることを示しています。

    考えられる根本的な原因は次のとおりです(完全なリストではありません):

    • SQL Serverに対する外部Windowsメモリの負荷により、メモリマネージャがバッファプールサイズを削減します
    • キャッシュの肥大化を計画して、バッファプールから余分なメモリを借用します
    • 次の理由により、(インデックスシークの代わりに)テーブル/クラスター化インデックススキャンを実行するクエリプラン。
      • ワークロード量の増加
      • パラメータスニッフィングの問題
      • 削除または変更された必須の非クラスター化インデックス
      • 暗黙の変換

    それを探すための1つのパターンは、テーブル/クラスター化されたインデックススキャンが原因であることが示唆されます。また、多数のCXPACKETが見られます。 PAGEIOLATCH_SHと一緒に待機します 待ちます。これは、大規模な並列テーブル/クラスター化インデックススキャンが発生していることを示す一般的なパターンです。

    いずれの場合も、PAGEIOLATCH_SHの原因となっているクエリプランを確認できます。 sys.dm_os_waiting_tasksを使用して待機します および他のDMV、およびここにある私のブログ投稿でそれを行うためのコードを入手できます。サードパーティの監視ツールを利用できる場合は、手を汚さずに原因を特定できる可能性があります。

    SQLSentryとPlanExplorerを使用したワークフローの例

    単純な(明らかに考案された)例では、SQL Sentryのツールスイートを使用しているクライアントシステムを使用していて、以下に示すように、SQLSentryのダッシュボードビューでI/O待機の急増が見られると仮定します。


    SQLSentryでI/O待機の急増を発見

    スパイクの前後の選択した時間間隔を右クリックしてから、トップSQLビューにジャンプして調査することにしました。これにより、実行された最もコストのかかるクエリが表示されます。


    時間範囲を強調表示してトップSQLに移動する

    このビューでは、スパイクが発生したときに実行されていた長時間実行クエリまたは高I / Oクエリを確認してから、クエリプランにドリルインすることを選択できます(この場合、長時間実行クエリは1つだけです。 1分近く実行されました):


    トップSQLで実行時間の長いクエリを確認する

    SQL Sentryクライアントでプランを確認するか、SQL Sentryプランエクスプローラーでプランを開くと、すぐに複数の問題が発生します。 7行を返すために必要な読み取り数が多すぎるようで、推定行と実際の行の差が大きく、計画では、シークが予想される場所でインデックススキャンが発生していることが示されています。


    クエリプランに暗黙の変換警告が表示される>

    このすべての原因は、SELECTの警告で強調表示されています 演算子:これは暗黙の変換です!

    暗黙的な変換は、検索述語のデータ型と検索対象の列のデータ型の不一致、または検索述語ではなくテーブル列で実行される計算によって引き起こされる潜行性の問題です。いずれの場合も、SQL Serverはテーブル列でインデックスシークを使用できず、代わりにスキャンを使用する必要があります。

    これは一見無害なコードで発生する可能性があり、一般的な例は日付計算を使用することです。顧客の年齢を格納するテーブルがあり、計算を実行して21歳以上の顧客の数を確認する場合は、次のようなコードを記述できます。

    WHERE DATEADD (YEAR, 21, [MyTable].[BirthDate]) <= @today;

    このコードでは、計算はテーブル列で行われるため、インデックスシークを使用できず、シークできない式(技術的には非SARG可能式と呼ばれます)とテーブル/クラスター化インデックススキャンが発生します。これは、計算を演算子の反対側に移動することで解決できます:

    WHERE [MyTable].[BirthDate] <= DATEADD (YEAR, -21, @today);

    基本的な列の比較で暗黙的な変換を引き起こす可能性のあるデータ型の変換が必要な場合、同僚のJonathan Kehayiasが、暗黙的な変換が必要になる場合のデータ型とメモのすべての組み合わせを比較する優れたブログ投稿を作成しました。

    概要

    過度のPAGEIOLATCH_XXという考えに陥らないでください 待機はI/Oサブシステムによって発生します。私の経験では、これらは通常SQL Serverと関係があることが原因であり、そこでトラブルシューティングを開始します。

    一般的な待機統計に関する限り、パフォーマンスのトラブルシューティングにそれらを使用する方法の詳細については、次のURLを参照してください。

    • 待機統計から始まる私のSQLskillsブログ投稿シリーズ、またはどこが痛いのか教えてください
    • 待機タイプとラッチクラスのライブラリはこちら
    • 私のPluralsightオンライントレーニングコースSQLServer:待機統計を使用したパフォーマンスのトラブルシューティング
    • SQL Sentry

    シリーズの次の記事では、ひざのけいれん反応の一般的な原因である別の待機タイプについて説明します。それまでは、トラブルシューティングを行ってください。


    1. mysqliプリペアドステートメントでnullを使用する

    2. OracleでのページングのためのLIMITおよびOFFSETの代替

    3. SQL ServerのFORMAT()でサポートされている標準の日付/時刻形式の文字列

    4. 単一の行をロックする方法