方法: "Active Query Index Hints" を使用してクエリの実行速度を遅くするIssue この記事は、ServiceNow にアクティブなクエリインデックスヒントを追加するタイミングと方法を明確にするためのものです。 ReleaseすべてのリリースResolution 対象者 MySQL データベースを使用する ServiceNow セルフホスト型顧客と、データベースオプティマイザーが最適でない実行計画を選択したときにクエリを改善する必要がある ServiceNow テクニカルサポートエンジニア。 警告:ServiceNow でホストされているお客様は、一般的な知識としてこの情報を参照できますが、以下の手順の多くを実行することはできません。ホストされている環境内でクエリのパフォーマンスが遅い場合は、ServiceNow サポートでケースを作成することを強くお勧めします。 トピック 時間のかかるクエリを特定するDB の遅さを確認するインデックス候補を判定するExplain Plan を取得する既存のインデックスを比較するインデックスヒントで改善をテストするアクティブクエリインデックスヒントのフォームを設定するクエリーヒントを定義する改善を確認する 遅いクエリーを特定します。 バックグラウンド: 以下のように、ホームページの遅さを訴える一部のユーザーが、Slow Queries モジュールを使用するホームページから時間のかかるクエリを特定しました。 先端: 影響が大きく、最適化が必要なクエリを確実にターゲットにするには、平均実行時間が 2000 ミリ秒>、実行回数が 500 >と表示され、サンプルの Java スタックトレースが Default-thread で始まる (インタラクティブなユーザートランザクションであることを意味する) フィルターオプションを検討してください。合計実行時間でリストを並べ替えると、最も重要なクエリが最初に表示されます。 ターゲットクエリを開き、[前回の発生] フィールドを調べて、クエリがまだパフォーマンスに影響を与えており、改善が必要であることを確認します。[例] フィールドの SQL をコピーし、任意のシンプルなテキストエディターに保存します。MS Word やその他のリッチエディターは使用しないでください。 DB の遅さを確認する 問題のインスタンスに使用されている MySQL データベースにアクセスし、同じ SQL クエリ (上記からコピー) を実行して、クエリが遅いことを確認します。 インデックス候補を判定する: 上記 SQL の where 句を見ると、次のタスクテーブル内の列の複合インデックスが適しているように思われます。 assignment_groupstateassigned_to これは現時点では単なる推測に過ぎませんが、現在使用されているインデックスがある場合は、それを確認してください。 Explain Plan を取得する: MySQL Explain Plan メカニズムを使用して、SQL クエリがアクセスする必要がある行数と、使用されているインデックスを確認します。 インデックスが使用されている間 (task_ref2)、結果に 0 行を返すために 200 万行にアクセスしていることに注意してください。データベースでこれを行うには 5.5 秒かかります。 既存のインデックスを比較する: task_ref2 インデックスがタスクテーブルのどの列から作成されたのかを確認します。 注意: MySQL バージョン 5.6 のテーブルは、合計 64 のインデックスに制限されています。この例では、タスクテーブルにすでに 62 個のインデックスがあります。一部のインデックスは複合 (複数列) であり、一部は単一列ですが、合計 64 のインデックス制限を超えることはできません。 ターゲットテーブルのインデックス数がすでに許容可能な最大値に近い場合は、より適切な既存のインデックスを探してください。 タスクテーブルの既存のインデックス付き列を確認すると、where 節の 3 つの列すべてをカバーする既存のインデックスがあります。現在使用されているインデックスtask_ref2オンは、上記のようにassigned_to列のみを持ち、アクティブです。 前述のとおり、where 句に基づく可能なインデックスは、次の列の複合インデックスである可能性があります。 assignment_groupstateassigned_to インデックス作成のメリットがあると思われる 3 つの列すべてを提供する既存の複合インデックスがあります。 インデックスヒントで改善をテストする: より良いインデックスがすでに存在することがわかったので、強制インデックスクエリヒントを使用して、クエリが高速化されるかどうかを確認します。 以前は、データベースオプティマイザーが最適と考えるインデックスを使用してこの同じクエリを行うのに 5.5 秒かかっていました。この新しく見つかった複合インデックスを使用すると、この頻繁に使用されるクエリのクエリ時間が約 4 秒短縮され、大幅に改善されます。これは、クエリヒントが明らかにパフォーマンスに役立つケースです。 注:OR 条件が複数あり IS NULL があることを考えると、このクエリは理想的ではありません。多くの場合、いくつかの異なる既存のインデックスを慎重に確認して試し、改善点が見つからない場合はクエリ自体を確認して書き直す必要があります。インデックスクエリの無視のヒントが、強制ヒントと同じかそれ以上に役立つことも起こり得ます。テストは、適切なソリューションを見つけるための鍵です。 アクティブクエリインデックスヒントのフォームを設定する (必要な場合): 注:PRB1439443 - アクティブクエリインデックスヒントは、エイリアスが切り詰められているテーブルでは機能しません。たとえば、論理名 x_nuvo_facilities_work_order を持つ x_nuvo_f8s_work_order という名前の物理テーブルは、インデックスヒントを受け取ることができません。回避策として、Active Query Rewriteを使用できます。 既存のインデックスを使用するとクエリの実行が高速化されることを確認したので、ServiceNow インスタンス内にアクティブなクエリインデックスヒントを作成できます。これまでは、クエリの実行を高速化する方法を見つけることがすべてでした。ここからは、プラットフォームに修正策を実装します。 フィルターナビゲーターに「Active Query Index Hints」と入力し、[新規] ボタンをクリックします。ページが以下のようにほぼ真っ黒に見える場合は、設定する必要があります。フォームにほかのフィールドもある場合は、次のセクションが表示されるまで下方向にスクロールします。 注:自己ホスト型の顧客は、このアクティブなクエリインデックスヒントモジュールにアクセスするために、ServiceNow にメンテナンスユーザー認証情報を要求する必要があります。 必要なフォームフィールドを追加するには、次の手順を実行します。 [>フォームレイアウトの構成] に移動します選択された次のフィールドを追加します。 上記のフォームレイアウトへの変更を保存すると、空のフォームは次のようになります。 アクティブなクエリのインデックスヒントを定義します。 スロークエリモジュールから、最も低速かつ最も頻度の高いクエリ (/home.do 呼び出し) を特定し、これを改善のターゲットとしました。次に、インデックス ヒントを強制すると、クエリの実行時間が大幅に改善されることがわかったため、Active Query Index Hint を定義します。 次の例のように、Example (target) query 、Table name (テーブル名)、Hint type (ヒントタイプ)、Index name (インデックス名)、および Correlation name (相関名) を入力します。次の点に注意してください。 上の黄色で強調表示された領域は、結果として得られるフォースヒントを名前ではなく列別に示しています。これはフォームの奇異な側面ではありますが、想定どおりに動作するはずです。保存すると、インデックスヒント例にインデックス名が表示されます。以下を参照してください。インデックス名選択ポップアップにはインデックス名で検索するオプションがありますが、選択すると列が表示されます。相関名は、クエリ自体からのテーブルエイリアスです。 テーブル名、ヒントタイプ、アクティブフラグ、およびその他の詳細を入力したら、ヒントを保存または送信します。検証プロセスが発生し、保存が成功すると、次のような青色の成功メッセージが表示されます。書き換え SQL の例 (上で赤く表示) を、データベースで以前にテストしたものと比較します。 注: スペーシング、特殊文字のコピーと貼り付け、埋め込みキャリッジリターンはすべて重要であり、プラットフォームのクエリヒントが正しく実装されない可能性があります。サンプルクエリに余分なスペースがある場合はスペースを維持する必要があります。クエリヒントも同じである必要があります。これが、特殊文字が誤ってヒントに挿入されないため、単純なテキストエディターが最も効果的である理由です。 改善を確認する: ターゲットの SQL 実行時間の改善は、いくつかの方法で確認できます。 クエリのソースがわかっている場合 (ページ上の特定のフィルター、レポート、ウィジェットなど) は、デバッグ SQL (詳細) を有効にし、プラットフォームがクエリの元のバージョンを、上記の強制インデックス ヒントで定義したものに適切に置き換えていることを確認できます。 この記事の冒頭にある元のクエリから、ソースが /home.do 呼び出しであったことがわかっています。この場合、ユーザーのホームページとウィジェットは既知であり、プラットフォームがデバッグ出力を介してクエリを適切に置き換えていることをすばやく確認できます。元のタイミングは、以前に定義されたインデックス ヒントを非アクティブに設定する (またはインデックス ヒントの前に直接検証する) ことですぐに使用できます クエリのソースが明確に理解されていない場合は、ターゲットクエリを識別するために最初に使用したのと同じパラメーターを使用してスロークエリモジュールを監視し、最後のサイティングがインデックスクエリのヒントの前の時間を表示するようにすることができます。新しい強制インデックスクエリーは、遅いクエリーモジュール内で適切なフィルター条件を使用して、最新の最終発生タイムスタンプでも表示される必要があります。次の例は、強制インデックスヒントが表示されたクエリの元のバージョンと新しいバージョンを示しています。 注: 検証とヒント作成のこの同じプロセスは、無視、強制、および使用のヒントタイプに使用できます。この注意書きは、それぞれに同等に適用できます。