MySQL チューニング シリーズ (6) - クエリの最適化

1. クエリが遅い理由

クエリ レートは、ネットワーク、CPU、IO、コンテキスト スイッチング、システム コール、生成統計、ロック待機時間などの要因の影響を受けます。
面接でよくある質問を考えてみましょう。
テーブルは非常に大きく、数億のデータが含まれています。パフォーマンスは低下しますか? テーブルにインデックスがある場合、
回答: 追加、削除、変更は遅くなります。(インデックスも動的に変更する必要があるため、SQL 実行の効率が低下します)。
クエリは必ずしも必要ではありません。特定のデータまたは少量のデータを具体的にクエリする場合、パフォーマンスはほとんど変わりません。大量のデータを同時にクエリすると、帯域幅やハードディスク ネットワークなどの影響によりクエリ効率が低下します。

2、クエリを最適化する

クエリ実行処理については、MySQLチューニングシリーズ(1) - パフォーマンス監視を参照してください。
クエリを実行する場合、まず SQL コマンドがパーサーに渡されると、意味論的な正当性を分類/検証するためにパーサーによって検証および解析されます。次に、オプティマイザはコストに基づいて最も効率的な実行計画を選択します。

1. アクセスされるデータ量を減らす

例として、ページ最適化
クエリ ステートメントは次のとおりです。

explain  select * from suoyin_test  limit 30000,1;

explain  select * from suoyin_test a join (select id from suoyin_test limit 30000,1) b on a.id = b.id;

実行結果は次のとおりです。
ここに画像の説明を挿入
ここに画像の説明を挿入
最適化の主な考え方:
まず、カバー インデックスを使用してフェッチするデータ行の主キーを取得し、次にこの主キー列を使用してデータ テーブルに関連付けます (クエリ データの量が少なくなってからクエリを実行します)。

2. 不要なデータフィルタリングを削減する

(1) 値を取得するためにlimitを使用するなど、すべての列を返さずに、必要に応じて列を返すようにしてください。
(2) 同じデータに複数回アクセスする場合は、キャッシュを使用できます。

3. オプティマイザの最適化タイプ

(1) 関連テーブルの順序を再定義します。データ テーブルの関連付けは、クエリで指定された順序で常に実行されるわけではありません。オプティマイザーは、関連付けの順序を決定する際の重要な機能です。
(2) アウター接続をインナー接続に変換すると、インナー接続の効率がアウター接続の効率よりも高くなります。
(3) 同等の変換ルールを使用することで、mysql は同等の変更をいくつか使用して式を簡素化し、計画することができます。
count、min、max などの集計関数を最適化します。インデックス付きのカラムを空にできるかどうかは、通常、mysql がそのような式を最適化するのに役立ちます。たとえば、特定のカラムの最小値を見つけるには、インデックスの左端のレコードをクエリするだけでよく、フルテキスト スキャンの比較は必要ありません。
(4) サブクエリの最適化。場合によっては、mysql はサブクエリをより効率的な形式に変換できるため、頻繁にクエリされるデータをキャッシュに入れるなど、データに複数回アクセスするための複数のクエリを減らすことができます。
(5) 等価伝播 (自動等価)。たとえば、リレーショナル クエリでは、2 つのテーブルの共通属性がフィルター条件として使用され、1 つだけ記述する必要があります。

4. アソシエーションクエリ

駆動テーブルにインデックスが付けられている場合、効率は非常に高くなりますが、インデックスが主キー インデックスでない場合は、テーブルに対してクエリを実行する必要があります。これに比べ、駆動テーブルのインデックスは主キー インデックスであり、より効率的です。具体的な参考文献: MySQL チューニング シリーズ (5) - インデックスの詳細な説明。

5. ソートの最適化

(1)ソートにはインデックススキャンを使用します。複合インデックスを作成する場合、デフォルトのインデックスの並べ替えは昇順であるため、その後複合インデックス列を使用して並べ替える場合は、すべての昇順またはすべての降順でインデックスを使用する必要があります。
(2)インデックスソートは使用しません。ダブルソートとシングルソートがあります。
ダブルソート: ディスクを 2 回スキャンして、最終的にデータを取得します。最初のデータ読み取りでは、並べ替えが必要なフィールドを読み取り、並べ替えます。2 回目は、並べ替え結果の必要性に応じてデータ行を読み取ります。(複数のランダム IO、データ読み取りのコストは比較的高くなります。)
単一ソート: クエリに必要なすべての列をディスクから読み取り、ソートし、ソートされたリストをスキャンして出力します。(効率が高く、二次読み取りを回避し、ランダム IO をシーケンシャル IO に変換しますが、高いメモリ領域が必要であり、大量のデータを保存できません。)
最適化戦略:

① sort_buffer_size パラメータの設定値(一方向ソートのメモリサイズ)を増やす
② max_length_for_sort_data パラメータの設定値(単一ソートフィールドのサイズ)を増やす
③ 選択後の不要なフィールドを削除する

6. カウントクエリの最適化

Count(*)、count(1)、および count(id) のクエリ速度は悪くありません。

7. グループ最適化

本質は、最初にソートしてからグループ化することであるため、最適化戦略はソートの最適化と同じです。可能であればインデックスをできるだけ使用するか、sort_buffer_size をできるだけ大きくして単一のソートに最適化します。

8. サブクエリの最適化

リレーショナル クエリ、内部結合を使用してみてください。

9. 重複排除クエリ

重複排除には、distinct キーワードを使用しないようにしてください。group by やインデックスを使用できます。

3. まとめ

概要を追加:索引が使用できる場合は索引を使用してください。

おすすめ

転載: blog.csdn.net/liwangcuihua/article/details/131101183