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 の非同期更新の簡単な分析

推薦する

Docker で ElasticSearch と Kibana をインストールするためのサンプル コード

1. はじめにElasticsearchは現在非常に人気があり、多くの企業が利用しているため、esを...

WeChatアプレットwebViewにH5を埋め込む方法の例

序文WeChat ミニプログラムは新しいオープン機能を提供します!ついにミニプログラムにHTMLペー...

Linux inotifyリアルタイムバックアップの実装方法の詳細説明

リアルタイム レプリケーションは、企業データをバックアップする最も重要な方法です。主に、ユーザーが送...

MySQL ストアド関数の詳細な紹介

目次1. ストアド関数を作成する2. ストアド関数の呼び出し3. 保存された関数を削除する4. スト...

簡単な手順で純粋な CSS3 で 3D 反転効果を実現

フロントエンド開発者の必須科目であるCSS3は、多くの基本的なアニメーション効果を実現するのに役立ち...

VMware 15.5 に CentOS7 をインストールするためのグラフィック チュートリアル

1. VMware 15.5で新しい仮想マシンを作成する1. VMware を開き、ホームページで「...

Vue+Openlayerはグラフィックスのドラッグと回転変形効果を実現します

目次序文関連資料成果を達成する実装手順序文Openlayer には独自の拡張プラグイン ol-ext...

Linux で複数のファイルの名前を一度に変更する方法

序文日常業務では、すべての jpg ファイルを bnp に変更したり、名前の 1 を one に変更...

js でシンプルなタブを実装する

タブ選択カードは、実際の Web ページで非常に頻繁に使用されます。基本的に、すべての Web ペー...

MySQL全文インデックスを使用して検索エンジンのサンプルコードの簡易版を実現する

序文全文インデックスを使用できるのは Innodb と MyISAM ストレージ エンジンのみです ...

Dockerコンテナでルート権限を取得する方法

まず、コンテナが稼働している必要がありますコンテナのCONTAINER IDは、sudo docke...

JSは文字列内の指定された文字列のn番目の出現位置を取得します

文字の位置を取得するための同様の方法について学習します。 charAt() 文字列内の指定された位置...

vue3.2 で追加された defineCustomElement の基本原理の詳細な説明

目次Webコンポーネントカスタム要素概要HTMLTemplateElement コンテンツ テンプレ...

Windows プラットフォームでの MySQL のインストールと設定方法と注意事項

2.1、msiインストールパッケージ2.1.1、インストール特に重要なのは、インストール前に、元の ...

MySQL 5.7.21 解凍版インストール Navicat データベース操作ツールインストール

MySQL解凍版とNavicatデータベース操作ツールのインストールは、以下のとおりです。 1. M...