1 つのプロダクションでの低速 SQL インデックスの最適化と考え方を覚えておく | JD Cloud テクニカル チーム

1. 問題の再発

暗く風が強いある夜、突然、操作バックエンド データベースの SQL が遅く、実際にかかった時間が 60 秒に達したことを示すアラームを受け取りました。



調べてみると、幸いなことに、それほど頻繁ではないため、より落ち着いて問題のトラブルシューティングを行うつもりです。これは、特定の条件下でインデックスに到達しないことが原因であるはずです。遅いクエリが頻繁に発生する場合は、データベース接続プールがいっぱいである可能性があります。データベースが使用できなくなり、アプリケーションが使用できなくなります。

2. トラブルシューティング

アラームには、検索に時間がかかる SQL ステートメントが含まれています。これは、非常に早く起動された SQL ステートメントです。SQL ステートメントは、以下に簡略化されています。

select * from xxx where gear_id=xxx and Investing=xxx order by id desc limit 10. これは、トラフィック プールの gear_id に基づく単純なクエリと、主キー ID の逆順の 10 個のデータのページング クエリです。

Examine=2 の場合はクエリ速度が非常に速いですが、examine=3 の場合はクエリ速度が非常に遅いため、さまざまな Exam で実行計画を確認すると、取得された実行計画は一貫しています。

実行プランを確認すると、 possible_keys に idx_gear_id インデックスがあることがわかりましたが、実際に使用されているキーは PRIMARY であり、where 条件は明らかにデータ フィルタリングのために余分に使用されています。ここまでで、この SQL が主キーのクラスター化インデックスをスキャンし、where ステートメントの条件を使用してフィルター処理することがわかりました。ここで時間が費やされます。

これは、異なる状態で検査にかかる時間が異なる理由も説明しています。これは、フィルタによってスキャンされた行の数に依存します。スキャンされた行が増えるほど、実行は遅くなります。ただし、同じ問題は既存のインデックス idx_gear_id には到達しません。

単一テーブルの数が少ない場合、インデックスの有無、主キーインデックススキャンか通常のインデックスかにかかわらず、非常に高速であり、これらの問題を無視するのは簡単です。は、こんにちは、私、こんにちは、そしてデータ量が増加し、それが数千万、数億に達すると、クエリが遅いという問題が顕著になります。

三原則分析

なぜ mysql はこの不適切な主キーのクラスター化インデックスを選択したのでしょうか?

一般的に使用されている InnoDb ストレージ エンジンを例として、クラスター化インデックス クエリと非クラスター化インデックス クエリの違いを見てみましょう。

クラスター化インデックス: 通常、B+ ツリーは各テーブルの主キーに基づいて構築され、テーブル全体の行レコード データはリーフ ノードに格納されます。つまり、データと主キーの両方がインデックス上にあります。

非クラスター化インデックス: テーブルのセカンダリ インデックス フィールド (一意のインデックス、ジョイント インデックスなど) から構築された B+ ツリー。リーフ ノードには、キー フィールド + 主キーの値、つまり、非クラスター化インデックスは依然としてインデックス ノードですが、最終的なデータ インデックスへのポインターを持っています。

クラスター化インデックス クエリの原則:

非クラスター化インデックス クエリ (セカンダリ インデックス クエリ) の原則:

上記のインデックス データ構造から、クラスター化インデックスはインデックスとデータを同じ B+ ツリーに格納するため、通常は非クラスター化インデックスよりもクラスター化インデックスからデータを取得する方が高速であることがわかります。リーフ ノードの主キーに到達した後、主キー インデックスを再度クエリする必要があります。つまり、行レコード データをテーブルにクエリして戻す必要があります。もちろん、クエリ対象の列が名前や年齢などのインデックス フィールドのみである場合は、結合インデックスを作成できます。つまり、インデックスに格納されているコンテンツが、クエリが必要なコンテンツになります。この種のクエリは、多くの場合、主キー インデックスよりも高速なこの種のインデックス クエリは、カバー インデックスとも呼ばれます。

返品フォームとは何ですか?

たとえば、上記のインデックス データを共通ユーザー テーブル user のインデックスにマッピングします。上記のクラスタード インデックスは、id フィールドを主キーとするインデックス、name フィールドは非クラスタード インデックス、その他のテーブル フィールドage は非インデックス フィールドです SQL の例: select * from user where id = 1; この SQL ステートメントはテーブルに戻る必要はありません。その理由は、主キー クエリ方式によれば、ID クラスタード インデックスの B+ ツリーを検索するだけで、対応するデータを見つけることができるためです。

ただし、非クラスター化インデックス名を使用して name = b のレコードをクエリする場合は、テーブルを使用する必要があります。その理由は、name のセカンダリ インデックス クエリ メソッドを使用して、最初に名前インデックス ツリーを検索し、次に主キー ID (PK の値が 1) を取得してから、クラスター化された主キー ID で再度検索する必要があるためです。インデックスツリー。セカンダリ インデックスに基づいて主キー ID をクエリし、次に主キー ID に基づいて主キー クラスタ化インデックスをクエリするこのプロセスは、テーブル リターンと呼ばれます。

MySQL がなぜこの不適切な主キーのクラスター化インデックスを選択したのかという質問に戻ります。MySQL の実行プログラムは、セカンダリ インデックスを使用して検索するにはデータが多すぎるため、並べ替えのためにディスクに一時的に保存してから並べ替える必要があると考えています。項目数が 10 個で、テーブルにフィールドをクエリする場合、パフォーマンスが非常に低下する可能性があるため、主キーのクラスタード インデックスを順番に直接スキャンし、where 条件の gear_id=xxx および Examin=xxx と比較します。アイテムは10個まで配置できますが、この場合、データ量が少ない場合は問題ありませんが、データ量が多い場合は、where条件を満たすデータが10個見つかるまで全データをスキャンする必要があります。 、消費時間も大幅に増加します。

4. 問題を解決する

問題を迅速に解決するには、強制インデックスを使用します。つまり、SQL ステートメントを作成するときに特定のインデックスを指定します。

SQL の例: select * from xxx 強制インデックス (idx_gear_id) where gear_id=xxx および検査=3 ID 説明制限 10 で並べ替えると、idx_gear_id インデックスの使用が強制されます。

以下は、強制インデックス作成を使用した実行計画です。

実際に使用されるインデックス キーは idx_gear_id であることがわかり、実行にかかる時間はわずか数百ミリ秒であり、バックエンドを操作するビジネス担当者にとっては完全に許容できる時間です。

5. 長期的な最適化

テーブル内のデータがますます多くなり、クエリ条件が複雑になり、クエリに json フィールドを使用することにも問題があるため、異種データを es クエリに使用し、json フィールドをフラット化することにしました。es は複雑なクエリ条件を自然にサポートしており、クエリの応答が速くなります。

es データ同期ソリューション:



ES データ同期リンクでは、JD Technology ミドルウェア DTS がデータベースのバイナリログを監視し、インデックス フィールド (クエリ条件フィールド) とビジネス固有 ID を ES に書き込みます。

複雑なクエリ条件に基づいてビジネス オペレーションをクエリする場合、最初に ES にアクセスしてクエリを実行し、一意のビジネス ID を見つけてから、一意のビジネス ID に基づいて DB 内の詳細なビジネス データをクエリします。これにより、ビジネス クエリとビジネス クエリの複雑さが同時に解決されます。クエリのパフォーマンス。

著者: JD Technology Zhang Shilei

出典:JD Cloud Developer Community 転載の際は出典を明記してください

SenseTime 創設者、Tang Xiaoou 氏が 55 歳で死去 2023 年、PHP は停滞 Wi-Fi 7 が完全に利用可能になる2024 年初頭にデビュー、Wi-Fi 6 の 5 倍高速 Hongmeng システムが独立しつつあり、多くの大学が「Hongmeng クラス」を設立 Zhihui Jun の新興企業が借り換え、金額は 6 億元を超え、事前評価額は 35 億元 Quark Browser PC 版が内部テストを開始 AI コード アシスタントは人気があり、プログラミング言語のランキングはすべてです できることは何もありません Mate 60 Pro の 5G モデムと無線周波数技術ははるかに先を行っています MariaDB が SkySQL を分割し、確立されました独立した企業として<​​/span> Xiaomi、Yu Chengdong 氏の Huawei からの「キールピボット」盗作声明に対応
{{名前}}
{{名前}}

おすすめ

転載: my.oschina.net/u/4090830/blog/10322126