MySQL 最適化技術における Limit クエリの最適化分析

MySQL 最適化技術における Limit クエリの最適化分析

序文

実際のビジネスでは、ページングは​​一般的なビジネス要件です。次に、制限クエリを使用します。制限クエリを使用すると、データが比較的小さい場合や、データの最初の部分のみがクエリされる場合に効率が非常に高くなります。ただし、データ量が大きい場合や、クエリ オフセットの数が多い場合 (limit 100000,20 など) は、効率が不十分になることがよくあります。一般的な方法は、Limit を order by と組み合わせて使用​​することです。order by にユーザー用のインデックスがある場合、効率は通常かなり良好です。

この場合、最も単純なクエリは、カバーリング インデックスを使用して特定の必要な列をクエリすることです。この効果は非常に良いです

下記の通り

mysql> SELECT * FROM 学生 LIMIT 1000000,1;
+---------+-------------+-------------+----------+--------+----------------------+
| id | first_name | last_name | created_at | score | updated_at |
+---------+-------------+-------------+----------+--------+----------------------+
| 1000001 | kF9DxBgnUi | yLXnPSHJpH | 2019-07-11 | 97 | 2019-07-11 14:29:59 | |
+---------+-------------+-------------+----------+--------+----------------------+
セット内1列(0.31秒)

時間を見ることができます

mysql> EXPLAIN SELECT score,first_name FROM student ORDER BY created_at LIMIT 1000000,20 \G
************************** 1. 行 ****************************
   id: 1
 選択タイプ: シンプル
  テーブル: 学生
 パーティション: NULL
   タイプ: インデックス
可能なキー: NULL
   キー: time_source_name
  キーの長さ: 69
   参照: NULL
   行数: 1000001
  フィルター: 100.00
  追加: インデックスの使用
セットに 1 行、警告 1 件 (0.00 秒)

マイSQL>

この方法では、クエリ対象の列はカバーリング インデックスを使用し、スキャンされる行数は大幅に削減されますが、効果はあまり満足のいくものではありません。他のクエリがある場合、そのようなクエリは非常に遅くなります。

たとえば、last_name 列を追加します。

次のように

mysql> SELECT score,first_name,last_name FROM student ORDER BY created_at LIMIT 1000000,1;
+-------+------------+------------+
| スコア | 名 | 姓 |
+-------+------------+------------+
| 86 | knKsV2g2fY | WB5qJeLZuk |
+-------+------------+------------+
セット1列目(4.81秒)

マイSQL>

このクエリの実行には 4 秒強かかります。分析により、このクエリではインデックスを使用できないことがわかります。

mysql> explain SELECT score,first_name,last_name FROM student ORDER BY created_at LIMIT 1000000,1\G
************************** 1. 行 ****************************
   id: 1
 選択タイプ: シンプル
  テーブル: 学生
 パーティション: NULL
   タイプ: すべて
可能なキー: NULL
   キー: NULL
  キー長さ: NULL
   参照: NULL
   行数: 6489221
  フィルター: 100.00
  追加: filesort の使用
セットに 1 行、警告 1 件 (0.00 秒)

マイSQL>

ここでクエリを次のように変更します。

mysql> SELECT student.score,student.first_name FROM student INNER JOIN (SELECT id FROM student ORDER BY created_at LIMIT 1000000,1 ) AS temp USING(id);
+-------+-------------+
| スコア | 名 |
+-------+-------------+
| 15 | 2QWZ |
+-------+-------------+
セット内1列(0.18秒)
mysql> EXPLAIN SELECT student.score,student.first_name,last_name FROM student INNER JOIN (SELECT id FROM student ORDER BY created_at LIMIT 1000000,1) AS temp USING(id);
+----+--------------+-------------+------------+----------+---------------+-----------------+----------+-----------+-----------+-------------+-------------+
| id | select_type | テーブル | パーティション | タイプ | 可能なキー | キー | キー長 | ref | 行 | フィルター済み | 追加 |
+----+--------------+-------------+------------+----------+---------------+-----------------+----------+-----------+-----------+-------------+-------------+
| 1 | PRIMARY | <derived2> | NULL | ALL | NULL | NULL | NULL | NULL | 1000001 | 100.00 | NULL |
| 1 | プライマリ | 学生 | NULL | eq_ref | プライマリ | プライマリ | 4 | temp.id | 1 | 100.00 | NULL |
| 2 | 派生 | 学生 | NULL | インデックス | NULL | time_source_name | 69 | NULL | 1000001 | 100.00 | インデックスを使用 |
+----+--------------+-------------+------------+----------+---------------+-----------------+----------+-----------+-----------+-------------+-------------+
セットに 3 行、警告 1 件 (0.00 秒)

分析結果から、この時点でクエリされたデータ レコードは 1000001 件だけであることがわかります。なぜこのような変化が起きたのでしょうか?これは遅延結合と呼ばれます。最初にカバーインデックスクエリを使用して必要な主キーを返し、次に主キーに基づいて元のテーブルを結合して必要なデータを取得するため、スキャンする必要がある行数が可能な限り削減されます。

特定の状況では、実際には別の最適化ソリューションが存在します。たとえば、最近挿入されたレコードをいくつか取得します。次に、最後のクエリの最後のレコードの主キー ID (last_id) を記録できます。
クエリは次のように変更できる。

SELECT score,first_name,last_name,id FROM student WHERE id>=last_id ORDER BY id ASC LIMIT 1

たとえば、last_id=1000000 の場合、クエリは 1000000 から開始されます。このようなシナリオでは、データのオフセットに関係なく、パフォーマンスは非常に良好になります。

要約する

以上がこの記事の全内容です。この記事の内容が皆様の勉強や仕事に何らかの参考学習価値をもたらすことを願います。123WORDPRESS.COM をご愛顧いただき、誠にありがとうございます。

以下もご興味があるかもしれません:
  • MySQL の制限クエリ文を最適化する 5 つの方法
  • MYSQL ページング制限速度の最適化方法が遅すぎる
  • MySQL 制限ページング最適化方法の共有
  • Mysqlの制限を最適化し、100万から1000万までの高速ページングの複合インデックスを参照し、軽量フレームワークに適用します。
  • MySQL クエリの最適化: LIMIT 1 はテーブル全体のスキャンを回避し、クエリの効率を向上させます
  • MySQL 制限オフセットの最適化の例
  • MySQL クエリの最適化: 結合クエリのソート制限の概要 (結合、順序、制限ステートメント)
  • PHP での MYSQL 制限の最適化
  • MySQL 制限クエリ最適化分析
  • Limitパラメータを使用してMySQLクエリを最適化する方法

<<:  Vue で 3D タグ クラウドを実装するための詳細なコード

>>:  Docker buildx を使用してマルチプラットフォーム イメージをビルドし、プライベート リポジトリにプッシュする方法

推薦する

JS 手ぶれ補正機能の実装と使用シナリオ

目次1. 手ぶれ補正機能とは何ですか? 1. なぜ手ぶれ補正機能が必要なのでしょうか? 2. 手ぶれ...

シンプルなドラッグ効果を実現するjs

この記事では、簡単なドラッグ効果を実現するためのjsの具体的なコードを参考までに共有します。具体的な...

JavaScript 配列メソッドの詳細な例

目次導入配列の作成作成方法詳しい説明方法参加する() push() と pop() shift() ...

Linuxにpipパッケージをインストールする方法

1. システムの Python バージョンに応じて、pip インストール パッケージをダウンロードし...

MySQL <> および <=> 演算子の紹介

<> 演算子機能: 等しくないことを示します。注: 「!=」演算子と同じ機能を持ちますが...

MySQL ツリー構造テーブルの設計と最適化に関する簡単な説明

序文多くの管理・オフィスシステムでは、ツリー構造がいたるところで見られます。たとえば、「部門」や「機...

Linux C++ マルチスレッド同期の非常に詳細な説明

目次1. ミューテックス1. ミューテックスの初期化2. ミューテックスロックの関連特性と分類3. ...

シェルスクリプト nginx 自動化スクリプト

このスクリプトは、nginxの起動、停止、再起動の操作を満たすことができます。 #!/bin/bas...

JavaScriptはクリックトグル機能を実装します

この記事の例では、クリックして切り替える機能を実装するためのJavaScriptの具体的なコードを参...

MySQL はどのようにしてデータベースの削除と暴走を効果的に防ぐことができますか?

目次セーフモード設定テスト1. where句なしで更新および削除する2. 非インデックスキーの削除3...

MySQL カーソル関数と使用法

目次意味カーソルの役割カーソルの使用カーソルの宣言カーソルを開くカーソルデータのトラバースカーソルを...

DockerHubイメージリポジトリの使い方の詳しい説明

これまで使用していたイメージはすべて DockerHub パブリック リポジトリから取得していました...

Linux redis-Sentinel 設定の詳細

ダウンロードダウンロードアドレス: https://redis.io/download /usr/l...

Reactはページング効果を実装する

この記事では、Reactでページング効果を実現するための具体的なコードを参考までに紹介します。具体的...

純粋な CSS で実装された大きなドロップダウン メニューのサンプル コード

これは純粋に CSS で実装された大きなドロップダウン メニューです。この大きなメニューは、js コ...