一部の選択データを含む一時テーブルを作成したい。
私の(奇妙な)問題は、同じクエリを複数回実行しなければならないことです。
CREATE TEMPORARY TABLE IF NOT EXISTS cache (id int(11) NOT NULL, INDEX (id))
SELECT id FROM table WHERE xyz;
CREATE TEMPORARY TABLE IF NOT EXISTS cache (id int(11) NOT NULL, INDEX (id))
SELECT id FROM table WHERE xyz;
残念ながら、一時テーブルはすでに存在していますが、MySQLは2番目のクエリを実行します。
SELECT
クエリが実行されるだけであることをMySQLに伝える方法はありますか?宜しくお願いします、
ティモ
これは、 _CREATE TEMPORARY TABLE
_ を使用したテーブル作成の性質です
テーブルを作成するときにTEMPORARYキーワードを使用できます。 TEMPORARYテーブルは現在の接続に対してのみ表示され、接続が閉じられると自動的に削除されます。これは、2つの異なる接続が互いに、または同じ名前の既存の非TEMPORARYテーブルと競合することなく、同じ一時テーブル名を使用できることを意味します。 (既存のテーブルは、一時テーブルが削除されるまで非表示になります。)一時テーブルを作成するには、CREATE TEMPORARY TABLES特権が必要です。
私の推測では、次の一連のイベントを実行している必要があります。
CREATE TEMPORARY TABLE
_を実行しましたCREATE TEMPORARY TABLE
_を再度実行する必要がありました特にMySQLレプリケーションに関しては、この問題が多くの開発者を犠牲にしているのを見てきました。たとえば、_STOP SLAVE;
_を実行すると、SQLスレッドが閉じます。 _CREATE TEMPORARY TABLE
_で作成されたテーブルはすべて削除されます。 _START SLAVE;
_を実行すると、INSERT、UPDATE、またはDELETEに必要なテーブルが存在しないため、MySQLレプリケーションは即座に中断します。リレーログでmysqlbinlogダンプを実行して元の_CREATE TEMPORARY TABLE
_ステートメントを特定し、_CREATE TABLE
_として実行して、テーブルがSQLスレッドを含む他のDB接続に引き続きアクセスできるようにする必要がありました_START SLAVE;
_が再発行されます。
あなたの質問について
SELECT
クエリが実行されるだけであることをMySQLに伝える方法はありますか?一時テーブルが存在するかどうかinformation_schemaを確認できません。 OSでは、 datadir
に_.frm
_が明示されていません。 tmpdir
で定義されたフォルダで見つけることができます。
次に例を示します。_test.junk
_という一時テーブルを作成し、テーブルの場所を探します。 (注:私はMySQL for Windowsを使用しています)
_Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.5.12-log MySQL Community Server (GPL)
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use test
Database changed
mysql> create temporary table junk (a int) engine=MyISAM;
Query OK, 0 rows affected (0.02 sec)
mysql> show create table junk\G
*************************** 1. row ***************************
Table: junk
Create Table: CREATE TEMPORARY TABLE `junk` (
`a` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
1 row in set (0.01 sec)
mysql> select count(1) from information_schema.tables
-> where table_schema='test' and table_name='junk';
+----------+
| count(1) |
+----------+
| 0 |
+----------+
1 row in set (0.08 sec)
mysql> show variables like 'datadir';
+---------------+-----------------------+
| Variable_name | Value |
+---------------+-----------------------+
| datadir | C:\MySQL_5.5.12\data\ |
+---------------+-----------------------+
1 row in set (0.00 sec)
mysql> show variables like 'tmpdir';
+---------------+--------------------------------------+
| Variable_name | Value |
+---------------+--------------------------------------+
| tmpdir | C:\Users\redwards\AppData\Local\Temp |
+---------------+--------------------------------------+
1 row in set (0.00 sec)
mysql>
_
テーブルはINFORMATION_SCHEMA.TABLESに表示されません。 OSでテーブルを見つけましょう
_C:\MySQL_5.5.12\data\test>cd
C:\MySQL_5.5.12\data\test
C:\MySQL_5.5.12\data\test>dir junk.*
Volume in drive C has no label.
Volume Serial Number is 2C92-485B
Directory of C:\MySQL_5.5.12\data\test
File Not Found
C:\MySQL_5.5.12\data\test>dir C:\Users\redwards\AppData\Local\Temp\*.frm
Volume in drive C has no label.
Volume Serial Number is 2C92-485B
Directory of C:\Users\redwards\AppData\Local\Temp
10/19/2012 11:04 AM 8,554 #sql7ac_3_0.frm
1 File(s) 8,554 bytes
0 Dir(s) 190,200,049,664 bytes free
C:\MySQL_5.5.12\data\test>dir C:\Users\redwards\AppData\Local\Temp\*.MY*
Volume in drive C has no label.
Volume Serial Number is 2C92-485B
Directory of C:\Users\redwards\AppData\Local\Temp
10/19/2012 11:04 AM 0 #sql7ac_3_0.MYD
10/19/2012 11:04 AM 1,024 #sql7ac_3_0.MYI
2 File(s) 1,024 bytes
0 Dir(s) 190,200,049,664 bytes free
C:\MySQL_5.5.12\data\test>
_
Tmpdirフォルダーに一時テーブルがあります。 mysqlクライアントを閉じて_dir C:\Users\redwards\AppData\Local\Temp\*.frm
_を実行すると、テーブルが消えました。
あなたは2つのことのいずれかを行うことができます
CREATE TEMPORARY TABLE IF NOT EXISTS
_を実行します(これは実際には不適切な設計へのバンドエイドですが、問題を回避する可能性があります)。同じDB接続を使用していてもこの問題が発生する場合は、これまでに言及されていない別の方法を使用してください。一時テーブルにインデックスを指定しました。一意のインデックスまたはプライマリキーである必要があります。
操作を_CREATE TABLE ... SELECT
_から_CREATE TABLE ... INSERT IGNORE
_にシフトできます
一時テーブルを使用する場合は、MyISAMを指定してください。 InnoDBは、クラッシュまたはDB接続の終了時に、ibdata1を使用してデータディクショナリに鳩の穴を残す傾向があります。
これら3つの観察を念頭に置いて、これが私の推奨される変更です
_CREATE TEMPORARY TABLE IF NOT EXISTS cache
(id int(11) NOT NULL, PRIMARY KEY (id)) ENGINE=MyISAM;
INSERT IGNORE INTO cache SELECT id FROM table WHERE xyz;
CREATE TEMPORARY TABLE IF NOT EXISTS cache
(id int(11) NOT NULL, PRIMARY KEY (id)) ENGINE=MyISAM;
INSERT IGNORE INTO cache SELECT id FROM table WHERE xyz;
_
試してみる !!!