連合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コード
目次1. 本来の定義2. JS操作、幅の変更を例に3. 効果: 幅が変更されました 1. 本来の定義...
VirtualBox をインストールした後、CentOS 7 をインストールします。ここでは詳細には...
長い間 MySQL を使ってきたので、SQL 文はすでに覚えていると思います。そこで、その実行原理を...
目次序文1. 概要2. 読み取りと書き込みの分離3. MySQL マスタースレーブレプリケーションの...
Vue に限定されず、他の種類の SPA プロジェクトにも当てはまる問題がいくつかあります。 1....
目次概要コールバックまたは高階関数とは何ですか?コールバック関数はどのように機能しますか?コールバッ...
序文:パーティショニングはテーブル設計パターンです。一般的に、テーブル パーティショニングとは、条件...
すべてがファイルです! UNIX はすでにそれを言っています。エリック・レイモンドはこう言いました。...
#docker ps チェック、すべてのポートがマップされています コンテナID イメージ コマンド...
ここ数年、Web デザインには「全幅背景と固定幅コンテンツ」というトレンドが生まれています。このデザ...
勉強や仕事で FTP サーバーを頻繁に使用する場合は、起動時に自動的に起動するように設定できます。設...
目次1. 接続管理2. オプティマイザレベルでの改善3. 機能の改善4. パフォーマンススキーマの最...
目次1. 動詞-if 2. <template> で v-if を使用する3. キーを使...
多くの場合、フォームを美しくするために、送信ボタンが画像に置き換えられます。ただし、細部に注意を払わ...
目次1. 応答原理の基盤2. コアオブジェクト: Dep と Watcher 3. 依存関係を収集し...