MySQL道普請便り
第107回 CREATE TEMPORARY TABLEによる一時テーブルの利用
MySQLには一時テーブルを利用するのに便利なCREATE TEMPORARY TABLE構文があります。これは利用しているセッション内だけで有効なテーブルを作成し,
今回はCREATE TEMPORARY TABLE構文の挙動を確認していきましょう。なお,
CREATE TEMPORARY TABLEを使って一時テーブルを作成する
一時テーブルを利用するには,CREATE TEMPORARY TABLES
権限を持つユーザーがCREATE TEMPORARY TABLE
構文を実施する必要があります。CREATE TEMPORARY TABLES権限は,
基本的に,
mysql> CREATE TEMPORARY TABLE tmp_t1 ( -> id INT, -> name varchar(256) -> ); Query OK, 0 rows affected (0.03 sec) mysql> CREATE TEMPORARY TABLE tmp_t2 (id INT, name varchar(256)) ROW_FORMAT = COMPRESSED; ERROR 3500 (HY000): CREATE TEMPORARY TABLE is not allowed with ROW_FORMAT=COMPRESSED or KEY_BLOCK_SIZE. mysql> SHOW WARNINGS; +-------+------+-------------------------------------------------------------------------------------+ | Level | Code | Message | +-------+------+-------------------------------------------------------------------------------------+ | Error | 3500 | CREATE TEMPORARY TABLE is not allowed with ROW_FORMAT=COMPRESSED or KEY_BLOCK_SIZE. | | Error | 1031 | Table storage engine for 'tmp_t2' doesn't have this option | +-------+------+-------------------------------------------------------------------------------------+
実際に同一セッション内でしか利用できないかconn1とconn2を利用して確認してみます。
conn1> CREATE TEMPORARY TABLE tmp_t1 as SELECT * FROM t1; Query OK, 2 rows affected (0.01 sec) Records: 2 Duplicates: 0 Warnings: 0 conn1> SELECT COUNT(1) FROM tmp_t1; +----------+ | COUNT(1) | +----------+ | 2 | +----------+ 1 row in set (0.00 sec) conn2> SELECT COUNT(1) FROM tmp_t1; ERROR 1146 (42S02): Table 'd1.tmp_t1' doesn't exist conn1> COMMIT RELEASE; Query OK, 0 rows affected (0.00 sec) conn1> SELECT COUNT(1) FROM tmp_t1; ERROR 2006 (HY000): MySQL server has gone away No connection. Trying to reconnect... Connection id: 93 Current database: d1 ERROR 1146 (42S02): Table 'd1.tmp_t1' doesn't exist
conn1で作成したtmp_COMMIT RELEASE
は,
TEMPORARY TABLEで作成したテーブルは,
conn1> CREATE TEMPORARY TABLE tmp as SELECT * FROM t1; conn2> CREATE TEMPORARY TABLE tmp as SELECT * FROM t2; conn1> SELECT * FROM tmp; +------+------+ | id | name | +------+------+ | 1 | test | | 1 | test | +------+------+ 2 rows in set (0.00 sec) onn2> SELECT * FROM tmp; +------+-------+ | id | point | +------+-------+ | 1 | 1 | | 2 | 2 | | 3 | 3 | +------+-------+ 3 rows in set (0.00 sec)
同じtmpテーブルで違う結果が表示されました。
CREATE TEMPORARY TABLEとレプリケーション
一時テーブルはBINLOG_
一方,
> SHOW STATUS like 'Slave_open_temp_tables'; +------------------------+-------+ | Variable_name | Value | +------------------------+-------+ | Slave_open_temp_tables | 0 | +------------------------+-------+ 1 row in set (0.01 sec)
一時テーブルを利用する時の注意点
利用を開始する前に確認しておいたほうが良い点があります。
一時テーブルの削除はTEMPORARYをつけたほうが良い
CREATE TEMPORARY TABLE構文で作成した一時テーブルはDROP構文で削除することは可能ですが,
SHOW TABLESコマンドではテーブルは表示されない
作成した一時テーブルはSHOW TABLESコマンドでは確認できません。もし自身のセッションの一時テーブルの存在確認をする場合は,
> SELECT * FROM INNODB_TEMP_TABLE_INFO; +----------+---------------+--------+------------+ | TABLE_ID | NAME | N_COLS | SPACE | +----------+---------------+--------+------------+ | 1577 | #sql3e04_1e_c | 6 | 4294501266 | | 1576 | #sql3e04_1e_1 | 6 | 4294501266 | +----------+---------------+--------+------------+ 2 rows in set (0.04 sec)
一時テーブルの名前変更はALTER文で
一時テーブルはRENAME構文を使って名前を変更することができません。もし一時テーブル名の名前を変更したい場合はALTER TABLE <元のテーブル名> RENAME TO <新しいテーブル名>
を使って変更します。
クエリ内で同じ一時テーブルを複数回使えない
違う一時テーブルであれば利用可能ですが,
mysql> SELECT * FROM tmp1 JOIN tmp1 as _tmp2 on tmp1.id = _tmp2.id; ERROR 1137 (HY000): Can't reopen table: 'tmp1'
その他の細かい注意点に関しては,
使い所
一時テーブルは同一セッション内でしか利用できませんが,
たとえば,
また,
まとめ
今回は一時テーブルの挙動と制限事項などを確認していきました。同一セッション内でしか利用はできませんが,
バックナンバー
MySQL道普請便り
- 第123回 ロッキングリードのNOWAITとSKIP LOCKEDオプションについて
- 第122回 DockerでMySQLをもっと便利に活用してみる
- 第121回 event_scheduler
- 第120回 events_statements_summary_by_digestテーブルのパラメータ
- 第119回 group_concat()を利用してgroup byを更に便利に使う
- 第118回 MySQL Routerを使って負荷分散を検証する
- 第117回 MySQL 8.0のオプティマイザーヒント
- 第116回 pt-upgradeを使ってインデックスチューニングの成果を確認する
- 第115回 mysqlshowコマンド
- 第114回 MySQL 8.0から使えるさまざまな権限について