it-swarm-eu.dev

MySQL: Provést CREATE TEMPORARY TABLE SELECT jen jednou?

Chci vytvořit dočasnou tabulku s některými vybranými daty.

Můj (podivný) problém je v tom, že musím udělat stejný dotaz více než jednou.

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 bohužel provede druhý dotaz, ačkoli dočasná tabulka již existuje.

OTÁZKY

  • Existuje způsob, jak říct MySQL, že vytvoření dočasné tabulky a dotazu SELECT jsou provedeny, pokud tabulka neexistuje?
  • Možná s podmínkou if?
  • Nebo mohu zkontrolovat nějaké informační schéma, pokud existuje dočasná tabulka? Díky za pomoc!

S pozdravem,

Timo

5
Timo

Zde je povaha vytváření tabulek s CREATE TEMPORARY TABLE

Při vytváření tabulky můžete použít klíčové slovo TEMPORARY. Tabulka TEMPORARY je viditelná pouze pro aktuální připojení a po ukončení připojení se automaticky zruší. To znamená, že dvě různá připojení mohou používat stejný název dočasné tabulky, aniž by došlo ke konfliktu mezi sebou nebo s existující ne-dočasnou tabulkou se stejným názvem. (Stávající tabulka je skrytá, dokud není zrušena dočasná tabulka.) Chcete-li vytvořit dočasné tabulky, musíte mít oprávnění CREATE TEMPORARY TABLES.

Myslím, že byste museli udělat následující sled událostí:

  • Běžel jsi CREATE TEMPORARY TABLE
  • Ukončené připojení DB (což způsobí okamžité zrušení tabulky dočasně)
  • Museli jste běžet CREATE TEMPORARY TABLE znovu, protože stůl neexistoval

Viděl jsem tento problém pronásledovat mnoho vývojářů, zejména pokud jde o replikaci MySQL. Pokud například spustíte STOP SLAVE;, vlákno SQL se zavře. Všechny tabulky se vytvářejí pomocí CREATE TEMPORARY TABLE bude vynecháno. Když spustíte START SLAVE;, MySQL Replication okamžitě přestane, protože tabulka potřebná pro VLOŽENÍ, UPDATE nebo DELETE již neexistuje. Musel jsem provést výpisy mysqlbinlog na protokolech relé, abych lokalizoval původní CREATE TEMPORARY TABLE příkazy, spusťte je jako CREATE TABLE, aby tabulka zůstala přístupná pro jiná připojení DB, včetně podprocesu SQL, když START SLAVE; je znovu vydáno.

Pokud jde o vaše otázky

  • Existuje způsob, jak říct MySQL, že vytvoření dočasné tabulky a dotazu SELECT jsou provedeny, pokud tabulka neexistuje?
  • Možná s podmínkou if-if?
  • Nebo mohu zkontrolovat nějaké informační schéma, pokud existuje dočasná tabulka?

Nemůžete zkontrolovat existenci dočasné tabulky v informačním schématu. V OS neexistuje žádný projev .frm in datadir . Najdete ji ve složce definované v tmpdir .

Zde je příklad: Vytvořím dočasnou tabulku s názvem test.junk a zkuste najít místo stolu. (Poznámka: Používám MySQL pro 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>

Tabulka není viditelná v INFORMATION_SCHEMA.TABLES. Vyhledejme tabulku v 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>

Ve složce tmpdir je dočasná tabulka. Když jsem zavřel klienta mysql a spustil dir C:\Users\redwards\AppData\Local\Temp\*.frm, stůl zmizel.

DOPORUČENÍ

Můžete udělat jednu ze dvou věcí

  1. Vytvořte dočasnou tabulku, nahrajte ji s daty, udržujte stejné připojení k DB a poté přistupujte k datům se stejným ProcessID.
  2. Do CREATE TEMPORARY TABLE IF NOT EXISTS (Toto je ve skutečnosti pomůcka pro nesprávné provedení, ale problém může obejít).

AKTUALIZACE 2012-12-18 13:06 EDT

Další pozorování č. 1

Pokud jste zůstali se stejným připojením k DB a stále máte tento problém, zde něco jiného, ​​co nebylo dříve uvedeno: Dali jste dočasné tabulce index. Mělo by to být JEDINEČNÝ INDEX nebo PRIMÁRNÍ KLÍČ.

Další pozorování č. 2

Operaci byste mohli přesunout z CREATE TABLE ... SELECT to CREATE TABLE ... INSERT IGNORE

Další pozorování # 3

Pokud chcete použít dočasné tabulky, zadejte MyISAM. InnoDB má tendenci nechat holubí díry v datovém slovníku s ibdata1 v případě havárie nebo po ukončení připojení DB.

S ohledem na tato tři (3) pozorování je zde moje doporučená změna

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;

Pokusit se !!!

2
RolandoMySQLDBA