連合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コード
Jenkins はオープンソース ソフトウェア プロジェクトです。Java をベースに開発された継続...
最近、Vue プロジェクトについて知り、ElementUI でデータを xlsx および Excel...
この記事では、WeChatアプレットのウォーターフォールフローページングスクロールロードを実装するた...
状況は以下のとおりです: (PS: 赤いボックスは iframe 領域を表し、灰色の四角形は上記の ...
Mysqlリモート接続構成を実装する2つの方法会社で働いていると、誰かのコンピュータに保存されている...
仮想マシン内の Ubuntu がネットワークに接続できない場合の効果的な解決策: 1. Ubuntu...
目次1. vuexとは何か2. インストールと導入3. vuexの使用4. プロセスの紹介5. 突然...
序文CSS を使用して点線を生成するのは、フロントエンド開発者にとっては簡単です。一般的に、これを実...
Vueドロップダウンリストの2つの実装最初の方法はv-forを使用する <el-select ...
最近、かなり暇です。大学4年生として数か月間インターンをしていました。インターンとして、Docker...
voidキーワードの紹介まず、void キーワードは JavaScript で非常に重要なキーワード...
DIVの背景は半透明ですが、DIV内の文字は半透明ではありませんコードをコピーコードは次のとおりです...
導入MySQL の SQL クエリ ステートメントで is null、is not null、!= ...
Vueのシンプルなタイマーを参考にしてください。具体的な内容は以下のとおりです原理: setInte...
最近、ポップアップ広告に取り組んでいました。デフォルト ページには z-index が設定されていな...