MySQLは「order by」がどのように機能するかを簡単に理解します

MySQLは「order by」がどのように機能するかを簡単に理解します

並べ替えの場合、order by は非常に頻繁に使用するキーワードです。インデックスに関するこれまでの知識とこの記事を組み合わせることで、インデックスを使用してスキャンするテーブル数を減らす方法や、ソート時に外部ソートを使用する方法について深く理解できるようになります。

まず、後で理解しやすいようにテーブルを定義します。

テーブル `t` を作成します (
 `id` int(11) NULLではない、
 `city` varchar(16) NOT NULL,
 `name` varchar(16) NOT NULL,
 `age` int(11) NOT NULL,
 `addr` varchar(128) デフォルト NULL,
 主キー (`id`)、
 キー `city` (`city`)
)ENGINE=InnoDB;

クエリ文を書きます

select city,name,age from t where city= ' 杭州' order by name limit 1000 ;

上記のテーブル定義によれば、city=xxx は定義したインデックスを使用できます。しかし、名前で並べ替えるためのインデックスがないことだけは明らかです。そのため、最初にインデックスを使用して city=xxx をクエリし、次にテーブルをクエリして、最後に並べ替える必要があります。

フルフィールドソート

cityフィールドにインデックスを作成した後、実行プランを使用してこのステートメントを表示します。

インデックスがあっても、ソートが必要であることを示すために「Using filesort」を使用していることがわかります。MySQL は、ソート用に sort_buffer と呼ばれるメモリを各スレッドに割り当てます。

上記の選択文を実行すると、通常は次のようなプロセスが実行されます。

1. sort_buffer を初期化し、name、city、age の 3 つのフィールドが追加されていることを確認します。

2. インデックス city から、条件 city='Hangzhou' を満たす最初の主キー ID を見つけます。

3. テーブルを返して、name、city、age の 3 つのフィールドの値を取得し、sort_buffer に格納します。

4. インデックス city から主キー ID レコードを取得します。

5. 都市が条件を満たさなくなるまで手順 3 ~ 4 を繰り返します。

6. sort_buffer 内のデータをフィールド名で素早くソートします。

7. ソート結果の最初の 1000 行がクライアントに返されます。

これをフルフィールドソートと呼びます。

名前によるソートは、メモリ内または外部ファイルを使用して実行できます。これは sort_buffer_size に依存します。 sort_buffer_size のデフォルト値は 1048576 バイト、つまり 1M です。ソートするデータの量が 1M 未満の場合、ソートはメモリ内で実行されます。ソートするデータの量が多く、メモリに格納できない場合は、ソートを補助するために一時ディスク ファイルが使用されます。

Rowidソート

1 行が非常に大きい場合、必要なすべてのフィールドを sort_buffer に入れてもあまり効果的ではありません。

MySQL には、ソート用の行データの長さを制御するために特に使用されるパラメータ max_length_for_sort_data があります。デフォルト値は 1024 です。この値を超えると、rowid ソートが使用されます。上記の文を実行するプロセスは次のようになります。

1. sort_buffer を初期化し、name と id の 2 つのフィールドを必ず設定します。

2. インデックス city から、条件 city = 'Hangzhou' を満たす最初の主キー ID を見つけます。

3. name フィールドと id フィールドをテーブルに返し、sort_buffer に格納します。

4. 条件を満たす次のレコードを取得し、手順 2 と 3 を繰り返します。

5. sort_buffer内の名前をソートします。

6. 結果を走査し、最初の 1000 行を取得します。次に、結果フィールドが ID に従ってテーブルから再度取得され、クライアントに返されます。

実際、すべての order by ステートメントで上記の二次ソート操作が必要なわけではありません。上記で分析した実行プロセスから、次のことがわかります。 MySQL が一時テーブルを生成する必要がある理由は、以前に取得したデータが順序付けられていないため、一時テーブルを並べ替える必要があるためです。

前のインデックスを変更して結合インデックスにすると、2 番目のフィールドから取得する値が実際に順序付けられます。

結合インデックスは、最初のインデックス フィールドが等しい場合に 2 番目のフィールドが順序付けられるという条件を満たします。

これにより、(city, name) インデックスを作成すると、city='Hangzhou' を検索するときに、ターゲットの 2 番目のフィールド名が実際に正しい順序になることが保証されます。したがって、クエリ プロセスは次のように簡素化できます。

1. インデックス (city, name) から、条件 city = 'Hangzhou' を満たす最初の主キー ID を見つけます。

2. テーブルから名前、都市、年齢の 3 つの値を返します。

3. IDを取得します。

4. レコード数が 1,000 件になるか、条件「city = 'Hangzhou'」が満たされなくなるまで、手順 2 と 3 を繰り返します。

また、クエリ処理ではインデックスの順序性を利用できるため、ソートしたりソートバッファを使用したりする必要がありません。

さらなる最適化は、前述のインデックス カバレッジです。クエリする必要のあるフィールドもインデックスでカバーされ、テーブルに戻るステップが省略されるため、クエリ全体が高速化されます。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • MySQL Order By 構文の紹介
  • MySQL Order by ステートメントの使用法と最適化の詳細な説明
  • MySQL の Order by ステートメントのクエリ効率を向上させる 2 つのアイデアの分析
  • MySQL の order by と group by シーケンスの問題の詳細な分析
  • インデックスを使用して MySQL ORDER BY ステートメントを最適化する方法
  • MySQL データベースのインデックス順序の詳細な説明

<<:  vuex での Getter の使用法の詳細な説明

>>:  Vue の DOM の非同期更新の簡単な分析

推薦する

フレックスとポジションの互換性の詳細な説明マイニングノート

今日は、すべてのブラウザ (主に IE 9 以上と Chrome) と互換性のある自分のホームページ...

MySQL のデータ削除とデータ テーブル メソッドの例

MySQL でデータやテーブルを削除するのは非常に簡単ですが、削除するとすべてのデータが消えてしまう...

MySQL データベースの詳細な説明 - 複数テーブル クエリ - 内部結合、外部結合、サブクエリ、相関サブクエリ

複数テーブルクエリ複数のテーブルから関連するクエリ結果を取得するには、単一の SELECT ステート...

vue フロントエンド HbuliderEslint リアルタイム検証 自動修復設定

目次HBuilderX での ESLint プラグインのインストールカスタム eslint-js ル...

Debian システムでの自動パッケージ更新の問題を解決する方法

いつから始まったのかはわかりませんが、コンピュータの電源を入れてインターネットに接続するたびに、デー...

MySQL 8.0 のメモリ関連パラメータの概要

理論的には、MySQL によって使用されるメモリ = グローバル共有メモリ + max_connec...

MySQL テーブル自動増分 ID オーバーフロー障害レビュー ソリューション

問題: MySQLテーブル内の自動増分IDのオーバーフローによりビジネスブロックが発生した背景: t...

Vue3における非親子コンポーネント通信の詳細な説明

目次最初の方法アプリ.vueホーム.vueホームコンテンツ.vueデータの応答性レスポンシブプロパテ...

Centos7 システムでの python2 と python3 の共存

最初のステップは、Python のバージョン番号とインストール パスを確認することです。 上記のビュ...

Vue+el-tableはセルの結合を実現します

この記事の例では、参考までにセルの結合を実現するためのel-tableの具体的なコードを共有していま...

CSS 表示属性のインラインブロックレイアウト実装の詳細な説明

CSS 表示プロパティ注: !DOCTYPE が指定されている場合、Internet Explore...

MySQL データベースは XA 仕様をどのように実装しますか?

MySQL 一貫性ログMySQL データベースの電源が切れた場合、コミットされていないトランザクシ...

Linux に JDK1.8 をインストールするための詳細なチュートリアル

1. 設置前の清掃 rpm -qa | grep jdk rpm -qa | grep gcj yu...

Redis を Docker コンテナとして素早くデプロイする方法

目次はじめるデータストレージサーバーを構成するRedis セキュリティの管理Redisインストールの...

フレックスレイアウトでコンテナ内のコンテンツを維持するためのソリューションの詳細な説明

モバイル側では、フレックスレイアウトが非常に便利です。デバイスの幅に応じてコンテナの幅を自動的に調整...