連合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. DockerはローカルディレクトリをマウントしますDocker は、ホスト上のディレクトリをイ...
Vue親コンポーネントは子コンポーネントの関数を呼び出す親コンポーネントはイベントを通じて子コンポー...
a href="#"> リンクをクリックすると、ページがページ上部までスク...
MySQL インストール手順 MySQL は、スウェーデンの MySQL AB によって開発された...
お使いのコンピュータが Mac の場合、homebrew を使用して MySQL をインストールする...
テーブル内の min-width と max-width プロパティの設定 <テーブル>...
水平方向では、行の配置を左、中央、右に設定できます。基本的な構文<TR ALIGN="...
以下のように表示されます。 mysql.proc から名前を選択します (db='データベー...
MYSQL のフィールドのデータの一部をバッチで置き換えます。具体的な導入は次のとおりです。 1....
この方法は、CSS3のdrop-shadow filterを使用して、png画像の不透明部分に任意の...
前回の記事 https://www.jb51.net/article/154157.htm では、B...
目次ヘッドレスブラウザとは何ですか?なぜ「ヘッドレス」ブラウザと呼ばれるのでしょうか?ヘッドレスブラ...
コードは次のようになります。 。プロセス{ 境界線:1px 実線 #B7B7B8; 背景:#F8F8...
Linux に PHP7 をインストールするにはどうすればいいですか? 1. 依存パッケージをインス...
「人間中心」と「グリーンデザイン」という2つの視点から考える——デザイン業界の同僚とも議論する2つの...