MySQL 8.0 リファレンスマニュアル


MySQL 8.0 リファレンスマニュアル  /  MySQL パフォーマンススキーマ  /  パフォーマンススキーマのステートメントダイジェストとサンプリング

27.10 パフォーマンススキーマのステートメントダイジェストとサンプリング

MySQL サーバーは、ステートメントダイジェスト情報を保守できます。 ダイジェストプロセスは、各 SQL ステートメントを正規化された形式 (ステートメントダイジェスト) に変換し、正規化された結果から SHA-256 ハッシュ値 (ダイジェストハッシュ値) を計算します。 正規化により、類似のステートメントがグループ化され、要約されて、サーバーが実行しているステートメントの種類とそれらが発生する頻度に関する情報が公開されます。 ダイジェストごとに、ダイジェストを生成する代表的なステートメントがサンプルとして格納されます。 このセクションでは、ステートメントのダイジェストとサンプリングがどのように行われるか、およびそれらがどのように役立つかについて説明します。

MySQL Enterprise Firewall やクエリーリライトプラグインなどの他の機能がステートメントダイジェストにアクセスできるように、パフォーマンススキーマが使用可能かどうかに関係なくパーサーでダイジェストが実行されます。

ステートメントダイジェストの一般概念

パーサーは、SQL ステートメントを受信すると、そのダイジェストが必要な場合にステートメントダイジェストを計算します。これは、次のいずれかの条件に該当する場合に当てはまります:

  • パフォーマンススキーマダイジェストインストゥルメンテーションは有効です

  • MySQL Enterprise Firewall は有効です

  • クエリーリライトプラグインは有効です

パーサーは、アプリケーションが SQL ステートメントから正規化されたステートメントダイジェストおよびダイジェストハッシュ値を計算するために呼び出すことができる STATEMENT_DIGEST_TEXT() および STATEMENT_DIGEST() 関数でも使用されます。

max_digest_length システム変数値は、正規化されたステートメントダイジェストの計算に使用できるセッション当たりの最大バイト数を決定します。 ダイジェスト計算中にその量の領域が使用されると、切捨てが発生: 解析されたステートメントからのそれ以上のトークンは収集されず、ダイジェスト値になりません。 解析されたトークンのバイト数が同じ正規化されたステートメントダイジェストを生成し、比較された場合、またはダイジェスト統計のために集計された場合にのみ、ステートメントが同じであるとみなされます。

正規化されたステートメントが計算されると、そこから SHA-256 ハッシュ値が計算されます。 さらに、次のようになります:

  • MySQL Enterprise Firewall が有効な場合は呼び出され、計算されたダイジェストが使用可能になります。

  • クエリーリライトプラグインが有効になっている場合は、そのプラグインがコールされ、ステートメントダイジェストおよびダイジェスト値が使用可能になります。

  • パフォーマンススキーマでダイジェスト計測が有効になっている場合は、正規化されたステートメントダイジェストのコピーが作成され、最大 performance_schema_max_digest_length バイトが割り当てられます。 したがって、performance_schema_max_digest_lengthmax_digest_length より小さい場合、コピーは元のコピーと相対的に切り捨てられます。 正規化されたステートメントダイジェストのコピーは、元の正規化されたステートメントから計算された SHA-256 ハッシュ値とともに、適切な「パフォーマンススキーマ」テーブルに格納されます。 (パフォーマンススキーマが元のステートメントダイジェストと相対的に正規化されたステートメントダイジェストのコピーを切り捨てる場合、SHA-256 ハッシュ値は再計算されません。)

ステートメントの正規化では、ステートメントのテキストがより標準化されたダイジェスト文字列表現に変換され、一般的なステートメントの構造は保持されますが、構造に不可欠でない情報は削除されます:

  • データベースまたはテーブル名などのオブジェクト識別子は保持されます。

  • リテラル値はパラメータマーカーに変換されます。 正規化されたステートメントは、名前、パスワード、日付などの情報を保持しません。

  • コメントが削除され、空白が調整されます。

これらのステートメントを考慮してください。

SELECT * FROM orders WHERE customer_id=10 AND quantity>20
SELECT * FROM orders WHERE customer_id = 20 AND quantity > 100

これらのステートメントを正規化するために、パーサーは ? によってデータ値を置換し、空白を調整します。 どちらのステートメントも同じ正規化形式になるため、同じとみなされます。

SELECT * FROM orders WHERE customer_id = ? AND quantity > ?

正規化されたステートメントは、格納される情報は少ないですが、引き続き元のステートメントを代表しています。 異なるデータ値を持つ他の同様のステートメントは、同じ正規化形式になります。

ここで、これらのステートメントを考慮してください。

SELECT * FROM customers WHERE customer_id = 1000
SELECT * FROM orders WHERE customer_id = 1000

この場合、オブジェクト識別子が異なるため、正規化されたステートメントは異なります:

SELECT * FROM customers WHERE customer_id = ?
SELECT * FROM orders WHERE customer_id = ?

正規化によってダイジェストバッファで使用可能な領域を超えるステートメント (max_digest_length によって決定) が生成された場合、切捨てが発生し、テキストは ... で終了します。 ... に続く部分のみが異なる長い正規化されたステートメントは、同じとみなされます。 これらのステートメントを考慮してください。

SELECT * FROM mytable WHERE cola = 10 AND colb = 20
SELECT * FROM mytable WHERE cola = 10 AND colc = 20

AND の直後にカットオフが発生した場合、両方のステートメントの形式は次のように正規化されます:

SELECT * FROM mytable WHERE cola = ? AND ...

この場合、2 つ目のカラム名の違いが失われ、両方のステートメントが同じとみなされます。

パフォーマンススキーマ内のステートメントダイジェスト

パフォーマンススキーマでは、ステートメントダイジェストには次の要素が含まれます:

  • setup_consumers テーブル内の statements_digest コンシューマは、パフォーマンススキーマがダイジェスト情報を保持するかどうかを制御します。 ステートメントダイジェストコンシューマを参照してください。

  • ステートメントイベントテーブル (events_statements_currentevents_statements_history および events_statements_history_long) には、正規化されたステートメントダイジェストおよび対応するダイジェスト SHA-256 ハッシュ値を格納するためのカラムがあります:

    • DIGEST_TEXT は、正規化されたステートメントダイジェストのテキストです。 これは、最大 max_digest_length バイトに計算され、必要に応じてさらに performance_schema_max_digest_length バイトに切り捨てられた元の正規化されたステートメントのコピーです。

    • DIGEST は、元の正規化されたステートメントから計算されたダイジェスト SHA-256 ハッシュ値です。

    セクション27.12.6「パフォーマンススキーマステートメントイベントテーブル」を参照してください。

  • events_statements_summary_by_digest サマリーテーブルには、集計されたステートメントダイジェスト情報が表示されます。 このテーブルは、SCHEMA_NAMEDIGEST の組合せごとにステートメントの情報を集計します。 パフォーマンススキーマは、SHA-256 ハッシュ値を集約に使用します。これらは、計算が高速で、衝突を最小限に抑える有利な統計分布を持つためです。 セクション27.12.18.3「ステートメントサマリーテーブル」を参照してください。

一部のパフォーマンステーブルには、ダイジェストの計算元となる元の SQL ステートメントを格納するカラムがあります:

  • events_statements_currentevents_statements_history および events_statements_history_long ステートメントイベントテーブルの SQL_TEXT カラム。

  • events_statements_summary_by_digest サマリーテーブルの QUERY_SAMPLE_TEXT カラム。

ステートメントの表示に使用できる最大領域は、デフォルトで 1024 バイトです。 この値を変更するには、サーバーの起動時に performance_schema_max_sql_text_length システム変数を設定します。 変更は、指定したすべてのカラムに必要な記憶域に影響します。

performance_schema_max_digest_length システム変数は、パフォーマンススキーマ内のダイジェスト値の格納に使用できるステートメントあたりの最大バイト数を決定します。 ただし、ステートメントのダイジェストの表示長は、キーワードやリテラル値などのステートメント要素の内部エンコーディングのため、使用可能なバッファサイズより長くなる場合があります。 したがって、ステートメントイベントテーブルの DIGEST_TEXT カラムから選択された値は、performance_schema_max_digest_length 値を超えるように見える場合があります。

events_statements_summary_by_digest サマリーテーブルには、サーバーによって実行されるステートメントのプロファイルが表示されます。 それは、アプリケーションが実行しているステートメントの種類とその頻度を示します。 アプリケーション開発者はこの情報をテーブル内のほかの情報と組み合わせて使用し、アプリケーションのパフォーマンス特性を査定できます。 たとえば、待機時間、ロック時間、またはインデックスの使用を示すテーブルカラムは不十分なクエリーの種類を強調表示することができます。 これにより、開発者が注意が必要なアプリケーションの部分を把握できます。

events_statements_summary_by_digest サマリーテーブルのサイズは固定です。 デフォルトでは、パフォーマンススキーマは起動時に使用するサイズを見積もります。 テーブルサイズを明示的に指定するには、サーバーの起動時に performance_schema_digests_size システム変数を設定します。 テーブルがいっぱいになると、パフォーマンススキーマは、SCHEMA_NAMEDIGEST の値がテーブル内の既存の値と一致しないステートメントを、SCHEMA_NAMEDIGESTNULL に設定された特殊な行にグループ化します。 これにより、すべてのステートメントがカウントされます。 ただし、特殊な行が実行されたステートメントのかなりの割合を占める場合は、performance_schema_digests_size を増やすことによってサマリーテーブルのサイズを増やすことをお勧めします。

ステートメントダイジェストメモリー使用

末尾のみが異なる非常に長いステートメントを生成するアプリケーションの場合、max_digest_length を増やすと、同じダイジェストに集約されるステートメントを区別するダイジェストの計算が可能になります。 逆に、max_digest_length を減らすと、サーバーはダイジェスト記憶域専用のメモリーが少なくなりますが、同じダイジェストに集計する長いステートメントの可能性が高くなります。 管理者は、特に多数の同時セッションを含むワークロード (サーバーがセッションごとに max_digest_length バイトを割り当てる) では、値を大きくすると、対応するメモリー要件が増加することに注意してください。

前述のように、パーサーによって計算される正規化されたステートメントダイジェストは最大 max_digest_length バイトに制約されますが、パフォーマンススキーマに格納される正規化されたステートメントダイジェストは performance_schema_max_digest_length バイトを使用します。 max_digest_length および performance_schema_max_digest_length の相対値に関して、次のメモリー使用上の考慮事項が適用されます:

  • max_digest_lengthperformance_schema_max_digest_length より小さい場合:

    • パフォーマンススキーマ以外のサーバー機能は、最大 max_digest_length バイトを占める正規化されたステートメントダイジェストを使用します。

    • パフォーマンススキーマは、格納されている正規化されたステートメントダイジェストをさらに切り捨てることはありませんが、ダイジェストあたりの max_digest_length バイト数よりも多くのメモリーを割り当てます。これは不要です。

  • max_digest_lengthperformance_schema_max_digest_length と等しい場合:

    • パフォーマンススキーマ以外のサーバー機能は、最大 max_digest_length バイトを占める正規化されたステートメントダイジェストを使用します。

    • パフォーマンススキーマは、格納されている正規化されたステートメントダイジェストをさらに切り捨てず、ダイジェストあたりの max_digest_length バイト数と同じ量のメモリーを割り当てます。

  • max_digest_lengthperformance_schema_max_digest_length より大きい場合:

    • パフォーマンススキーマ以外のサーバー機能は、最大 max_digest_length バイトを占める正規化されたステートメントダイジェストを使用します。

    • パフォーマンススキーマは、格納されている正規化されたステートメントダイジェストをさらに切り捨て、ダイジェストあたりの max_digest_length バイト数より少ないメモリーを割り当てます。

パフォーマンススキーマのステートメントイベントテーブルには多くのダイジェストが格納される可能性があるため、max_digest_length より小さい performance_schema_max_digest_length を設定すると、管理者は次の要素のバランスを取ることができます:

  • パフォーマンススキーマ外のサーバー機能で使用可能な長い正規化されたステートメントダイジェストが必要です

  • 多くの同時セッション。それぞれがダイジェスト計算メモリーを割り当てます

  • 多数のステートメントダイジェストを格納するときに、パフォーマンススキーマステートメントイベントテーブルによるメモリー消費を制限する必要がある

performance_schema_max_digest_length 設定はセッションごとではなく、ステートメントごとであり、セッションは events_statements_history テーブルに複数のステートメントを格納できます。 このテーブルの典型的なステートメントの数はセッションごとに 10 であるため、各セッションは、このテーブルのみに対して performance_schema_max_digest_length 値で示されるメモリーの 10 倍を消費します。

また、多くのステートメント (およびダイジェスト) がグローバルに収集されており、特に events_statements_history_long テーブルにあります。 ここでも、格納された N ステートメントは、performance_schema_max_digest_length 値で示されたメモリーの N 倍を消費します。

SQL ステートメントの格納およびダイジェスト計算に使用されるメモリー量を評価するには、SHOW ENGINE PERFORMANCE_SCHEMA STATUS ステートメントを使用するか、次のインスツルメントを監視します:

mysql> SELECT NAME
       FROM performance_schema.setup_instruments
       WHERE NAME LIKE '%.sqltext';
+------------------------------------------------------------------+
| NAME                                                             |
+------------------------------------------------------------------+
| memory/performance_schema/events_statements_history.sqltext      |
| memory/performance_schema/events_statements_current.sqltext      |
| memory/performance_schema/events_statements_history_long.sqltext |
+------------------------------------------------------------------+

mysql> SELECT NAME
       FROM performance_schema.setup_instruments
       WHERE NAME LIKE 'memory/performance_schema/%.tokens';
+----------------------------------------------------------------------+
| NAME                                                                 |
+----------------------------------------------------------------------+
| memory/performance_schema/events_statements_history.tokens           |
| memory/performance_schema/events_statements_current.tokens           |
| memory/performance_schema/events_statements_summary_by_digest.tokens |
| memory/performance_schema/events_statements_history_long.tokens      |
+----------------------------------------------------------------------+

ステートメントサンプリング

パフォーマンススキーマは、ステートメントサンプリングを使用して、events_statements_summary_by_digest テーブル内の各ダイジェスト値を生成する代表的なステートメントを収集します。 これらのカラムには、サンプルステートメントの情報が格納されます: QUERY_SAMPLE_TEXT (ステートメントのテキスト)、QUERY_SAMPLE_SEEN (ステートメントが表示されたとき) および QUERY_SAMPLE_TIMER_WAIT (ステートメントの待機時間または実行時間)。 パフォーマンススキーマは、サンプルステートメントを選択するたびに 3 つのカラムすべてを更新します。

新しいテーブル行が挿入されると、行ダイジェスト値を生成したステートメントは、ダイジェストに関連付けられた現在のサンプルステートメントとして格納されます。 その後、同じダイジェスト値を持つほかのステートメントがサーバーに表示されるときに、新しいステートメントを使用して現在のサンプルステートメントを置き換えるかどうか (つまり、再サンプリングするかどうか) を決定します。 リサンプリングポリシーは、現在のサンプルステートメントと新しいステートメントの比較待機時間、およびオプションで現在のサンプルステートメントの経過時間に基づきます:

  • 待機時間に基づくリサンプリング: 新しいステートメントの待機時間が現在のサンプルステートメントの待機時間よりも長い場合は、現在のサンプルステートメントになります。

  • 年齢に基づくリサンプリング: performance_schema_max_digest_sample_age システム変数の値がゼロより大きく、現在のサンプルステートメントが何秒以上経過している場合、現在のステートメントは「古すぎます」とみなされ、新しいステートメントで置き換えられます。 これは、新しいステートメントの待機時間が現在のサンプルステートメントの待機時間より短い場合でも発生します。

デフォルトでは、performance_schema_max_digest_sample_age は 60 秒 (1 分) です。 経過時間による expire ステートメントのサンプリング速度を変更するには、値を増減します。 リサンプリングポリシーのエージベース部分を無効にするには、performance_schema_max_digest_sample_age を 0 に設定します。


関連キーワード:  ステートメント, テーブル, ダイジェスト, パフォーマンス, スキーマ, digest, max, length, events, performance