連合UNIONセマンティクス: 2つのサブクエリの結果を結合し、重複行を1行だけ保持します。 テーブルの初期化テーブル t1(id INT 主キー、a INT、b INT、インデックス(a)) を作成します。 区切り文字 ;; CREATE PROCEDURE idata() 始める i INT を宣言します。 i=1 を設定します。 (i<= 1000) の場合 t1 VALUES (i,i,i) に挿入します。 i=i+1 を設定します。 終了しながら; 終わり;; 区切り文字 ; idata() を呼び出します。 ステートメントの実行(SELECT 1000 AS f) UNION (SELECT id FROM t1 ORDER BY id DESC LIMIT 2); mysql> EXPLAIN (SELECT 1000 AS f) UNION (SELECT id FROM t1 ORDER BY id DESC LIMIT 2); +----+--------------+-------------+-----------+--------+---------------+---------+-------+------+-------+---------+----------------------------------+ | id | select_type | テーブル | パーティション | タイプ | 可能なキー | キー | キー長 | ref | 行 | フィルター済み | 追加 | +----+--------------+-------------+-----------+--------+---------------+---------+-------+------+-------+---------+----------------------------------+ | 1 | PRIMARY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | テーブルは使用されていません | | 2 | UNION | t1 | NULL | index | NULL | PRIMARY | 4 | NULL | 2 | 100.00 | 後方インデックススキャン。インデックスを使用 | | NULL | UNION RESULT | <union1,2> | NULL | ALL | NULL | NULL | NULL | NULL | NULL | NULL | 一時を使用 | +----+--------------+-------------+-----------+--------+---------------+---------+-------+------+-------+---------+----------------------------------+ 2行目の
連合の結果
ユニオンオール
mysql> EXPLAIN (SELECT 1000 AS f) UNION ALL (SELECT id FROM t1 ORDER BY id DESC LIMIT 2); +----+-------------+--------+-----------+---------+-------+---------------+---------+-------+-------+--------+---------+----------------------------------+ | id | select_type | テーブル | パーティション | タイプ | 可能なキー | キー | キー長 | ref | 行 | フィルター済み | 追加 | +----+-------------+--------+-----------+---------+-------+---------------+---------+-------+-------+--------+---------+----------------------------------+ | 1 | PRIMARY | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | テーブルは使用されていません | | 2 | UNION | t1 | NULL | index | NULL | PRIMARY | 4 | NULL | 2 | 100.00 | 後方インデックススキャン。インデックスを使用 | +----+-------------+--------+-----------+---------+-------+---------------+---------+-------+-------+--------+---------+----------------------------------+ グループ化十分なメモリ-- 16777216 バイト = 16 MB mysql> '%tmp_table_size%' のような変数を表示します。 +----------------+----------+ | 変数名 | 値 | +----------------+----------+ | tmp_table_size | 16777216 | +----------------+----------+ ステートメントの実行-- MySQL 5.6 で実行mysql> EXPLAIN SELECT id%10 AS m, COUNT(*) AS c FROM t1 GROUP BY m; +----+-------------+-------+-------+-------+---------------+-------+------+------+----------------------------------------------+ | id | select_type | テーブル | タイプ | possible_keys | key | key_len | ref | 行 | 追加 | +----+-------------+-------+-------+-------+---------------+-------+------+------+----------------------------------------------+ | 1 | SIMPLE | t1 | index | PRIMARY,a | a | 5 | NULL | 1000 | インデックスを使用; 一時を使用; ファイルソートを使用 | +----+-------------+-------+-------+-------+---------------+-------+------+------+----------------------------------------------+ mysql> SELECT id%10 AS m, COUNT(*) AS c FROM t1 GROUP BY m; +------+-----+ | m | c | +------+-----+ | 0 | 100 | | 1 | 100 | | 2 | 100 | | 3 | 100 | | 4 | 100 | | 5 | 100 | | 6 | 100 | | 7 | 100 | | 8 | 100 | | 9 | 100 | +------+-----+ 一時テーブルの使用:
実行プロセス
選別プロセスNULL による順序-- 最終的なソート段階をスキップし、一時テーブルから直接データを取得します。mysql> EXPLAIN SELECT id%10 AS m, COUNT(*) AS c FROM t1 GROUP BY m ORDER BY NULL; +----+-------------+-------+-------+---------------+-------+-------+------+------------------------------+ | id | select_type | テーブル | タイプ | possible_keys | key | key_len | ref | 行 | 追加 | +----+-------------+-------+-------+---------------+-------+-------+------+------------------------------+ | 1 | SIMPLE | t1 | インデックス | PRIMARY,a | a | 5 | NULL | 1000 | インデックスを使用; 一時を使用 | +----+-------------+-------+-------+---------------+-------+-------+------+------------------------------+ -- t1 のデータは 1 から始まります。mysql> SELECT id%10 AS m, COUNT(*) AS c FROM t1 GROUP BY m ORDER BY NULL; +------+-----+ | m | c | +------+-----+ | 1 | 100 | | 2 | 100 | | 3 | 100 | | 4 | 100 | | 5 | 100 | | 6 | 100 | | 7 | 100 | | 8 | 100 | | 9 | 100 | | 0 | 100 | +------+-----+ メモリ不足tmp_table_size を 1024 に設定します。 ステートメントの実行-- メモリ一時テーブルの上限は 1024 バイトですが、メモリ一時テーブルは 100 行のデータを完全に保持することはできません。メモリ一時テーブルはディスク一時テーブルに変換され、InnoDB エンジンがデフォルトで使用されます。 -- t1 が非常に大きい場合、このクエリに必要なディスク一時テーブルは大量のディスク領域を占有します。 mysql> SELECT id%100 AS m, count(*) AS c FROM t1 GROUP BY m ORDER BY NULL LIMIT 10; +------+----+ | m | c | +------+----+ | 1 | 10 | | 2 | 10 | | 3 | 10 | | 4 | 10 | | 5 | 10 | | 6 | 10 | | 7 | 10 | | 8 | 10 | | 9 | 10 | | 10 | 10 | +------+----+ 最適化計画インデックスを最適化する一時テーブルがメモリ内で使用されるかディスク上で使用されるかに関係なく、 一時テーブルが必要な理由: 各行の 入力データが順序どおりであることを保証できる場合は、
-- MySQL 5.7 で ALTER TABLE t1 ADD COLUMN z INT GENERATED ALWAYS AS(id % 100), ADD INDEX(z) を実行します。 -- カバーリング インデックスが使用され、一時テーブルやソートは必要ありません。mysql> EXPLAIN SELECT z, COUNT(*) AS c FROM t1 GROUP BY z; +----+-------------+--------+-----------+---------+---------------+-------+--------+----------+-----------+-------------+ | id | select_type | テーブル | パーティション | タイプ | 可能なキー | キー | キー長 | ref | 行 | フィルター済み | 追加 | +----+-------------+--------+-----------+---------+---------------+-------+--------+----------+-----------+-------------+ | 1 | SIMPLE | t1 | NULL | インデックス | z | z | 5 | NULL | 1000 | 100.00 | インデックスを使用 | +----+-------------+--------+-----------+---------+---------------+-------+--------+----------+-----------+-------------+ 2 直接ソート
一時ディスク テーブルを直接使用し、 ディスク一時テーブルは元々 B+ ツリー ストレージを使用しますが、これは配列ストレージほど効率的ではありません。オプティマイザーは
実行プロセス-- 一時テーブルは使用されませんが、ソート アルゴリズムは直接使用されます。mysql> EXPLAIN SELECT SQL_BIG_RESULT id%100 AS m, COUNT(*) AS c FROM t1 GROUP BY m; +----+-------------+-------+-------+-------+---------------+-------+------+------+------+-----------------------------+ | id | select_type | テーブル | タイプ | possible_keys | key | key_len | ref | 行 | 追加 | +----+-------------+-------+-------+-------+---------------+-------+------+------+------+-----------------------------+ | 1 | SIMPLE | t1 | index | PRIMARY,a | a | 5 | NULL | 1000 | インデックスを使用; ファイルソートを使用 | +----+-------------+-------+-------+-------+---------------+-------+------+------+------+-----------------------------+ t1のインデックスaをスキャンし、その中のid値を1つずつ取り出し、id%100の値を スキャンが完了したら、 ソート後、順序付けられた配列が得られます。順序付けられた配列を走査して、各値が出現する回数を取得します (上記のインデックスを最適化する方法と同様)。 DISTINCTとの比較-- 標準SQL、SELECT部分に集計関数COUNT(*)を追加します SELECT a,COUNT(*) FROM t GROUP BY a ORDER BY NULL; -- 非標準SQL SELECT a FROM t GROUP BY a ORDER BY NULL; SELECT DISTINCT a FROM t; 標準SQL: フィールド a でグループ化し、各グループに a が出現する回数を数える 非標準SQL:
集計関数が必要ない場合、
まとめ
参考文献「MySQL実践45講義」 これで、MySQL 内部一時テーブルの具体的な使用法に関するこの記事は終了です。MySQL 内部一時テーブルに関するより詳しい情報は、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: VMware 仮想マシンに固定 IP アドレスを設定する方法 (グラフィック チュートリアル)
>>: 太陽系の惑星のアニメーション効果を実現するHTML+CSS3コード
目次序文Toastコンポーネントをカプセル化する方法ユースケース具体的な実装要約する序文ビジネスが発...
目次dnsmasq をインストールして設定するChinaDNS をインストールして設定するshado...
Docker の作成Docker Compose は、管理対象コンテナをプロジェクト、サービス、コン...
目次1. CentOS 7.9 20にDockerをインストールする2. MySQL クラスターをデ...
Tomcat CentOS インストールこのインストール チュートリアルでは、次の内容について説明し...
この記事では、モグラ叩きゲームを実装するためのJavaScriptの具体的なコードを参考までに紹介し...
目次チュートリアルシリーズ1. MySQL アーキテクチャクエリキャッシュキャッシュされないクエリ:...
私が書いた内容が理解できない場合は、インターネット上に理解できるチュートリアルがない可能性があります...
この記事では、MySQL の ROUND 関数を使用した丸め操作の落とし穴を例を使って説明します。ご...
1. ビデオタグFirefoxでは自動再生をサポートしますが、GoogleとIEではサポートしません...
1. 対照的な色を使用します。ここでのコントラストとは、テキストの色と背景色のコントラストを指します...
1: nginx のインストール方法については詳しく説明しません。Baidu で検索してください。 ...
CSS では、要素タグは、要素の表示モードの違いに応じて、インラインレベル要素とブロックレベル要素の...
前回のブログでは、Nginx と httpd を使用して、逆生成用のバックエンド Tomcat サー...
カーネル: [root@opop ~]# cat /etc/centos-release CentO...