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 を使用してマルチプラットフォーム イメージをビルドし、プライベート リポジトリにプッシュする方法

推薦する

CentOS での MySQL ログイン 1045 問題を解決する

アプリケーション全体を CentOS にデプロイする必要があるため、当然ながらデータベース操作は不可...

js の hasOwnProperty のプロパティとインスタンスの使用法の詳細な説明

1. js は hasOwnProperty が不正に占有されることから保護しません。オブジェクトに...

VueはEchartsを使用して3次元棒グラフを実装します

この記事では、Echartsを使用して3次元棒グラフを実装するVueの具体的なコードを参考までに共有...

Vue elementUI フォームのネストされたテーブルと各行の検証の詳細な説明

目次エフェクト表示コードリンクキーコード表形式データコンポーネントのネスト検証方法リセット方法完全な...

Vue3 がデータ監視を実装するためにプロキシを使用する理由の分析

Vue データの双方向バインディング原則ですが、この方法には欠点があり、配列とオブジェクトの部分的な...

MySQL データベース データのロード 複数の用途

目次MySQL Load Dataの多様な用途1. LOAD の基本的な背景2. 基本パラメータをロ...

MySQL インポートおよびエクスポートのバックアップの詳細

目次1. MySQLのバックアップタイプの詳細な説明1. バックアップがデータベースに与える影響に基...

Windows サーバー ファイルをローカルにバックアップする方法、Windows サーバー データ バックアップ ソリューション

重要なデータはバックアップする必要があり、リアルタイムでバックアップする必要があります。そうしないと...

CSS 読み込み効果の実装 パックマン

えーっと、名前はただの推測です 2333序文これは練習用の CSS デモです。何か間違っている点があ...

Raspberry Pi 4 に Ubuntu 19.10 をインストールするための詳細なチュートリアル

以前、raspbian で実行したときに opencv の一部の依存関係をパッケージ化できず、一部の...

Nginx 500 内部サーバーエラーの解決方法

今日、Nginxを使っていたら500エラーが発生しました。エラーコードを検索してみんなに共有しました...

React コードを共有するためのベストプラクティス

プロジェクトがある程度複雑になると、必然的にロジックの再利用の問題に直面することになります。 Rea...

MySQL の時間設定に関する考慮事項の詳細な要約

時間は本当に存在するのでしょうか?時間は人間が考え出した概念に過ぎず、物事の変化を測る基準に過ぎない...

MySQL で null 値と空文字 ('') を区別する

日常の開発では、データベースの追加、削除、変更、クエリが一般的に行われるため、Mysql で NUL...

HTML メタの使用例

使用例コードをコピーコードは次のとおりです。 <!DOCTYPE html> <!...