連合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コード
<br />Web テーブル フレームを作成するためのヒント。 ------------...
参照ドキュメント公式 Docker インストール ドキュメント: https://docs.dock...
まず、nginx コンテナ内の構造:コンテナを入力します: docker exec -it b511...
環境: 1. CentOS6.5 X64 2.mysql-5.6.34-linux-glibc2.5...
目次1 Java環境の設定2 tomcatのインストールと展開Tomcat をインストールして展開す...
序文休日は終わっていますが、それは別の形で(お腹に触れることで)私たちに現れます。ミニプログラムでデ...
1. mysqlをインストールします。 udo apt-getでmysql-serverをインストー...
テーブル構造とそのデータをコピーする次のステートメントは、データを新しいテーブルにコピーします。注:...
CentOS 7にPostgreSQL 11をインストールする PostgreSQL: 世界で最も先...
最初の方法: skip-grant-tables: 非常に便利なmysql起動パラメータ非常に便利な...
簡単に言うと、今日は Gitlab-CI を使用してリモート サーバーに自動的にデプロイする方法につ...
Ubuntu 20.04 がリリースされ、多くの新機能が導入されましたが、慣れていない機能も多くあ...
META タグは、HTML 言語のヘッダー領域にある補助タグです。作成者、日時、Web ページの説明...
目次スムーズなアニメーションの基準方法1: Chromeデベロッパーツールを使用する方法 2: フレ...
目次1. 問題2. 解決策2.1 ページングコンポーネント2.2 データベースデータを取得する関数:...