標準の Group by ステートメントには、select a,count(*) from t group by a; などの並べ替え、グループ化、集計関数が含まれています。このステートメントでは、並べ替えにデフォルトで a が使用されます。列 a にインデックスがない場合、 a と count(*) をカウントするための一時テーブルが作成され、次に sort_buffer を通じて a でソートされます。 標準的な実行プロセス構造: テーブル t1(id int 主キー、a int、b int、インデックス(a)) を作成します。 デリミタ;; プロシージャ idata() を作成する 始める iをintとして宣言します。 i=1 に設定します。 i<=1000の間、 t1 に値 (i, i, i) を挿入します。 i=i+1 と設定します。 終了しながら; 終わり;; 区切り文字 ; idata() を呼び出す。 この関数は、(1,1,1) から (1000,1000,1000) までの 1000 個のステートメントを t1 に挿入します。 select id%10 as m, count(*) as c from t1 group by m; を実行します。 分析: インデックスを使用するということは、このステートメントがカバーリング インデックスを使用してインデックス a を選択するため、テーブルに戻る必要がないことを意味します。 プロセス: 1. 2 つのフィールド m と c を持つ一時メモリ テーブルを作成します。主キーは m です。 ステップ 2 メモリ内の一時テーブルに格納されているフィールドの合計長がパラメータ tmp_table_size で設定されたサイズに達したことが検出された場合、メモリ内の一時テーブルはディスク上の一時テーブルにアップグレードされ、トラバーサル計算が再開されます。 最終的なソートは、下の図の破線ボックス内の操作です。sort_buffer のサイズが十分に大きくない場合は、ソートを補助するために一時テーブルが使用されます。 最適化最適化されていない (つまり、グループ化列にインデックスがない) group by の全体的なプロセスは、次のように要約できます。データは順序付けられていないため、一時テーブルを作成する必要があり、次に各データがどのグループに属するかを 1 つずつ判断し、最後にグループ化列に従って並べ替えます。したがって、最適化には 2 つのアプローチがあります。 並べ替えを削除返されたデータをソートする必要がない場合は、ソートを禁止できます。つまり、上記のステートメントを select a,count(*) from t group by a order by null に変更します。 並べ替えレコードがソートフィールドによってソートされている場合、データは次のような構造になります。 このように、実際に返されるフィールドを取得したり、集計関数を計算したりするときには、順番にアクセスしていくだけで済みます。列の値が次のものになったときに、現在のグループアクセスが終了し、以前にカウントされたデータが直接返されることがわかります。これにより、一時テーブルの作成が回避され、ソートでは sort_buffer を使用した追加のソートが必要なくなります。これにより実行効率が大幅に向上します。 成し遂げる1. グループ化フィールドがインデックスの作成に適している場合は、グループ化フィールドのインデックスを直接作成します。 MySQL バージョン 5.7 は、列データの関連する更新を実装するために使用される生成列メカニズムをサポートしています。次のように列zを作成し、z列にインデックスを作成します(MySQL 5.6以前の場合は、通常の列とインデックスを作成してこの問題を解決することもできます) テーブル t1 を変更し、列 z int を追加し、常に as(id % 100) として生成し、インデックス (z) を追加します。 次に解析します: 一時テーブルや追加のソートは使用されないため、パフォーマンスが向上します。 2. グループ化フィールドが適切でない(使用率が非常に低い)場合は、SQL_BIG_RESULT を使用して最適化を試みることができます。 SQL_BIG_RESULT ヒントを group by ステートメントに追加することで、このステートメントには大量のデータが含まれており、一時ディスク テーブルを直接使用する必要があることをオプティマイザーに伝えることができます。 MySQL オプティマイザーは、ディスク一時テーブルが B+ ツリーに格納されており、そのストレージ効率は配列ほど高くないことを認識します。したがって、SQL_BIG_RESULT は大量のデータを示すために使用されるため、ディスク容量を考慮すると、配列に直接格納する方が適切です。したがって、SQL_BIG_RESULT を使用した後、オプティマイザーは配列構造のディスク一時テーブルを使用します。 ただし、ディスク一時テーブルを使用する条件が満たされていない場合、ディスク一時テーブルは使用されません。つまり、sort_buffer スペースが、返されてソートされるフィールドの合計長を格納できる場合、配列構造 sort_buffer が使用されます。合計フィールドが sort_buffer サイズを超える場合、ソートを支援するために配列構造のディスク一時テーブルが追加されます。 sort_buffer に十分なスペースがある場合、データは sort_buffer 内でソートされ、インデックスとして機能します。 上記の例を引き続き使用して、SQL_BIG_RESULTを使用します。 テーブル t1 を変更し、列 z int を追加し、常に as(id % 100) として生成し、インデックス (z) を追加します。 具体的なプロセスは以下のとおりです。 1. sort_buffer を初期化し、そこに整数フィールド (m で示される) を配置します。 分析: この時点では一時テーブルは使用されていないことがわかりますが、ソートには sort_buffer が直接使用され、一時テーブルの使用によって発生するパフォーマンスの消費が抑えられます。 要約する1. group by ステートメントの結果をソートする必要がない場合は、ステートメントの後に order by null を追加します。通常、一時テーブルを使用する必要はありません (上記の 2 つの最適化は、どちらもソートが必要であるという前提で提案されています)。 以上がMySQL Group by最適化の詳細な説明です。MySQL Group by最適化の詳細については、123WORDPRESS.COMの他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
<<: CSS中級者向けアダプティブレイアウトの5つのソリューションの詳細な説明
>>: docker windows10共有ディレクトリのマウント失敗の解決策
まず、MySQL InnoDB エンジンのストレージ形式に関する重要なポイントをいくつか紹介します。...
結合クエリ結合クエリとは、2 つ以上のテーブル間のマッチング クエリを指し、一般的には水平操作と呼ば...
1. インストール前の準備データベースのバージョンを確認するコマンド: mysql --versio...
次に、ログ管理、ログのアーカイブ、ログのトラブルシューティング、イベントの転送と収集のためのコンピュ...
ネイティブJavaScriptでスキニングを実装するための具体的なコードは参考までに。具体的な内容は...
Vue 3.x プロジェクトの作成 npm init @vitejs/app my-vue-app ...
序文クエリの最適化は一夜にして達成できるものではありません。対応するツールの使い方を学び、他の人の経...
500 (内部サーバー エラー) サーバーでエラーが発生したため、要求を完了できませんでした。 50...
目次1.ライフサイクルとは何か2. Vueのライフサイクル3. ライフサイクルフック関数1.ライフサ...
はじめに: MySQL では、CONCAT() 関数を使用して複数の文字列を 1 つの文字列に連結し...
[解決策1: パディングの実装]原理:要素の padding の値がパーセンテージの場合、このパーセ...
1. ポート 80 が占有されているかどうかを確認します。通常、ポート 80 は Apache サー...
目次序文:特定の操作ステップ1: プレハブを準備するステップ2: オブジェクトプールを初期化するステ...
login.html 部分: <!DOCTYPE html> <html lang...
マスタースレーブレプリケーションモードのクラスターでは、通常、1 つのマスターノードと 2 つ以上の...