MySQL臨時表

MySQL臨時表

 




 

MySQL 臨時表

MySQL 臨時表在咱們須要保存一些臨時數據時是很是有用的。臨時表只在當前鏈接可見,當關閉鏈接時,Mysql會自動刪除表並釋放全部空間。 html

臨時表在MySQL 3.23版本中添加,若是你的MySQL版本低於 3.23版本就沒法使用MySQL的臨時表。不過如今通常不多有再使用這麼低版本的MySQL數據庫服務了。 java

MySQL臨時表只在當前鏈接可見,若是你使用PHP腳原本建立MySQL臨時表,那每當PHP腳本執行完成後,該臨時表也會自動銷燬。 mysql

若是你使用了其餘MySQL客戶端程序鏈接MySQL數據庫服務器來建立臨時表,那麼只有在關閉客戶端程序時纔會銷燬臨時表,固然你也能夠手動銷燬。 面試

實例

如下展現了使用MySQL 臨時表的簡單實例,如下的SQL代碼能夠適用於PHP腳本的mysql_query()函數。 sql

>mysql> CREATE TEMPORARY TABLE SalesSummary (
    -> product_name VARCHAR(50) NOT NULL
    -> , total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
    -> , avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
    -> , total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);
Query OK, 0 rows affected (0.00 sec)


mysql> INSERT INTO SalesSummary
    -> (product_name, total_sales, avg_unit_price, total_units_sold)
    -> VALUES
    -> ('cucumber', 100.25, 90, 2);


mysql> SELECT * FROM SalesSummary;
+--------------+-------------+----------------+------------------+
| product_name | total_sales | avg_unit_price | total_units_sold |
+--------------+-------------+----------------+------------------+
| cucumber     |      100.25 |          90.00 |                2 |
+--------------+-------------+----------------+------------------+
1 row in set (0.00 sec)

 

當你使用 SHOW TABLES命令顯示數據表列表時,你將沒法看到 SalesSummary表。 數據庫

若是你退出當前MySQL會話,再使用 SELECT命令來讀取原先建立的臨時表數據,那你會發現數據庫中沒有該表的存在,由於在你退出時該臨時表已經被銷燬了。 數組


刪除MySQL 臨時表

默認狀況下,當你斷開與數據庫的鏈接後,臨時表就會自動被銷燬。固然你也能夠在當前MySQL會話使用 DROP TABLE 命令來手動刪除臨時表。 性能優化

如下是手動刪除臨時表的實例: 服務器

mysql> CREATE TEMPORARY TABLE SalesSummary (
    -> product_name VARCHAR(50) NOT NULL
    -> , total_sales DECIMAL(12,2) NOT NULL DEFAULT 0.00
    -> , avg_unit_price DECIMAL(7,2) NOT NULL DEFAULT 0.00
    -> , total_units_sold INT UNSIGNED NOT NULL DEFAULT 0
);
Query OK, 0 rows affected (0.00 sec)


mysql> INSERT INTO SalesSummary
    -> (product_name, total_sales, avg_unit_price, total_units_sold)
    -> VALUES
    -> ('cucumber', 100.25, 90, 2);


mysql> SELECT * FROM SalesSummary;
+--------------+-------------+----------------+------------------+
| product_name | total_sales | avg_unit_price | total_units_sold |
+--------------+-------------+----------------+------------------+
| cucumber     |      100.25 |          90.00 |                2 |
+--------------+-------------+----------------+------------------+
1 row in set (0.00 sec)
mysql> DROP TABLE SalesSummary;
mysql>  SELECT * FROM SalesSummary;
ERROR 1146: Table 'RUNOOB.SalesSummary' doesn't exist

 


 

MySQL中臨時表的基本建立與使用教程

當工做在很是大的表上時,你可能偶爾須要運行不少查詢得到一個大量數據的小的子集,不是對整個表運行這些查詢,而是讓MySQL每次找出所需的少數記錄,將記錄選擇到一個臨時表可能更快些,而後在這些表運行查詢。微信

建立臨時表很容易,給正常的CREATE TABLE語句加上TEMPORARY關鍵字:

CREATE TEMPORARY TABLE tmp_table (
 name VARCHAR(10) NOT NULL,
 value INTEGER NOT NULL
)

 

臨時表將在你鏈接MySQL期間存在。當你斷開時,MySQL將自動刪除表並釋放所用的空間。固然你能夠在仍然鏈接的時候刪除表並釋放空間。

DROP TABLE tmp_table

 

若是在你建立名爲tmp_table臨時表時名爲tmp_table的表在數據庫中已經存在,臨時表將有必要屏蔽(隱藏)非臨時表tmp_table。

若是你聲明臨時表是一個HEAP表,MySQL也容許你指定在內存中建立它:

CREATE TEMPORARY TABLE tmp_table (  
 name VARCHAR(10) NOT NULL,
 value INTEGER NOT NULL
) TYPE = HEAP

 

由於HEAP表存儲在內存中,你對它運行的查詢可能比磁盤上的臨時錶快些。然而,HEAP表與通常的表有些不一樣,且有自身的限制。詳見MySQL參考手冊。

正如前面的建議,你應該測試臨時表看看它們是否真的比對大量數據庫運行查詢快。若是數據很好地索引,臨時表可能一點不快。

臨時表再斷開於mysql的鏈接後系統會自動刪除臨時表中的數據,可是這隻限於用下面語句創建的表:

定義字段:

CREATE TEMPORARY TABLE tmp_table (
 name VARCHAR(10) NOT NULL,
 value INTEGER NOT NULL 
)

 

直接將查詢結果導入臨時表

CREATE TEMPORARY TABLE tmp_table SELECT * FROM table_name

 

另外mysql也容許你在內存中直接建立臨時表,由於是在內存中全部速度會很快,語法以下:

CREATE TEMPORARY TABLE tmp_table (
 name VARCHAR(10) NOT NULL,
 value INTEGER NOT NULL
) TYPE = HEAP

 

 從上面的分析能夠看出臨時表的數據是會被清空的,你斷開了鏈接就會被自動清空,可是你程序中不可能每發行一次sql就鏈接一次數據庫吧(若是是這樣的話,那就會出現你擔憂的問題,若是不是就沒有問題),由於只有斷開數據庫鏈接纔會被清空數據,在一個數據庫鏈接裏面發行屢次sql的話系統是不會自動清空臨時表數據的。

只有在當前鏈接狀況下, TEMPORARY 表纔是可見的。當鏈接關閉時, TEMPORARY 表被自動取消。這意味着兩個不一樣的鏈接可使用相同的臨時表名稱,同時兩個臨時表不會互相沖突,也不與原有的同名的非臨時表衝突。(原有的表被隱藏,直到臨時表被取消時爲止。)必須擁有 CREATE TEMPORARY TABLES 權限,才能建立臨時表。能夠經過指定 ENGINE|TYPE = MEMORY; 來指定建立內存臨時表。

若是表已存在,則使用關鍵詞 IF NOT EXISTS 能夠防止發生錯誤。注意,原有表的結構與 CREATE TABLE 語句中表示的表的結構是否相同,這一點沒有驗證。註釋:若是在 CREATE TABLE...SELECT 語句中使用 IF NOT EXISTS ,則不論表是否已存在,由 SELECT 部分選擇的記錄都會被插入。

DROP TEMPORARY TABLE 語句只取消 TEMPORARY 表,語句不會終止正在進行中的事務。在採用鏈接池的狀況下,爲防止屢次 CREATE 、 DROP TEMPORARY TABLE 帶來的性能瓶頸,可使用 CREATE IF NOT EXISTS + TRUNCATE TABLE 的方式來提高性能。

臨時表支持主鍵、索引指定。在鏈接非臨時表查詢能夠利用指定主鍵或索引來提高性能。

CREATE PROCEDURE sp_test_tt(IN i_chars VARCHAR(50),OUT o_counts BIGINT)
BEGIN
     create temporary table if not exists tmpTable – 不存在則建立臨時表
     (
      objChk varchar(255) primary key,
      ModelName varchar(50),
      Operator varchar(500),
      PModelName varchar(50)
     );
     truncate TABLE tmpTable; -- 使用前先清空臨時表。
 
     insert into tmpTable values(i_chars,i_chars,i_chars,i_chars);
     insert into tmpTable values(i_chars,i_chars,i_chars,i_chars); -- 語句1
     select * from tmpTable; -- 語句2
     select count(*) into o_counts from tmpTable; -- 語句3
END;

 

上述代碼語句 1 返回臨時表中全部數據,語句 2 將總記錄數寫入輸出參數。 truncate 語句放在 create 以後,而不是整個存儲過程最後,緣由在於隨後的語句 1 插入一樣的值,二臨時表 PK 校驗將產生一個錯誤,則存儲過程最終異常結束。綜合異常處理,能夠以下修改,以在每次存儲過程調用完畢後清除臨時表。
再來看一個例子:

CREATE PROCEDURE sp_test_tt(IN i_chars VARCHAR(50),OUT o_counts BIGINT)
BEGIN
     create temporary table if not exists tmpTable
     (
      objChk varchar(255) primary key,
      ModelName varchar(50),
      Operator varchar(500),
      PModelName varchar(50)
     ) ENGINE = MEMORY;
     begin
          declare exit handler for sqlwarning,NOT FOUND,SQLEXCEPTION set o_counts=-1;
          insert into tmpTable values(i_chars,i_chars,i_chars,i_chars);
          select * from tmpTable; -- 語句1
          select count(*) into o_counts from tmpTable;
     end;
     truncate TABLE tmpTable; -- 語句2
END;

 

雖然上述代碼語句 2 最後 truncate table 清空了所有臨時表數據,但前面語句 1 select 的數據結果集不會被清除。已經過 java 程序驗證。

臨時表能夠解決二維數組輸出的問題。可是,大批量的數據插入只能由程序採用循環來作。某些特殊狀況下的輸入數組,例如選擇好的一組待刪除數據的 ID 的輸入,也只能利用循環來作。臨時表也不適用於須要三維數組的狀況。



經過CREATE TEMPORARY TABLE 建立的臨時表,這種臨時表稱爲外部臨時表。這種臨時表只對當前用戶可見,當前會話結束的時候,該臨時表會自動關閉。這種臨時表的命名與非臨時表能夠同名(同名後非臨時表將對當前會話不可見,直到臨時表被刪除)。

內部臨時表

內部臨時表是一種特殊輕量級的臨時表,用來進行性能優化。這種臨時表會被MySQL自動建立並用來存儲某些操做的中間結果。這些操做可能包括在優化階段或者執行階段。這種內部表對用戶來講是不可見的,可是經過EXPLAIN或者SHOW STATUS能夠查看MYSQL是否使用了內部臨時表用來幫助完成某個操做。內部臨時表在SQL語句的優化過程當中扮演着很是重要的角色, MySQL中的不少操做都要依賴於內部臨時表來進行優化。可是使用內部臨時表須要建立表以及中間數據的存取代價,因此用戶在寫SQL語句的時候應該儘可能的去避免使用臨時表。

內部臨時表有兩種類型:一種是HEAP臨時表,這種臨時表的全部數據都會存在內存中,對於這種表的操做不須要IO操做。另外一種是OnDisk臨時表,顧名思義,這種臨時表會將數據存儲在磁盤上。OnDisk臨時表用來處理中間結果比較大的操做。若是HEAP臨時表存儲的數據大於MAX_HEAP_TABLE_SIZE(詳情請參考MySQL手冊中系統變量部分),HEAP臨時表將會被自動轉換成OnDisk臨時表。OnDisk臨時表在5.7中能夠經過INTERNAL_TMP_DISK_STORAGE_ENGINE系統變量選擇使用MyISAM引擎或者InnoDB引擎。



mysql的內存表和臨時表

內存表:

session 1      
$ mysql -uroot      
root@(none) 10:05:06>use test      
Database changed      
root       @test 10:06:06>CREATE TABLE tmp_memory (i INT) ENGINE = MEMORY;      
Query OK, 0 rows affected (0.00 sec)      
root       @test 10:08:46>insert into tmp_memory values (1);      
Query OK, 1 row affected (0.00 sec)      
root       @test 10:08:46>      


session2      
$ mysql -uroot test      
root       @test 10:05:12>CREATE TABLE tmp_memory (i INT) ENGINE = MEMORY;      
ERROR 1050 (42S01): Table 'tmp_memory' already exists      
root@test 10:16:27>select * from tmp_memory;      
+------+      
| i |      
+------+      
| 1 |      
+------+      
row in set (0.00 sec)      

1. 多個session,建立表的名字不能同樣

2. 一個session建立會話後,對其餘session也是可見的
3. data目錄下只有tmp_memory.frm ,表結構放在磁盤上,數據放在內存中
4. mysql 重啓或者關閉後內存表裏的數據會丟失,可是表結構仍然存在
5. 能夠建立索引,刪除索引,支持惟一索引
6. 不影響主備,主庫上插入的數據,備庫也能夠查到
7. show tables 看獲得表

臨時表:

session1      
$ mysql -uroot test      
root@test 10:30:18>CREATE TEMPORARY TABLE tmp_table (name VARCHAR(10) NOT NULL,value INTEGER NOT NULL);      
Query OK, 0 rows affected (0.05 sec)      
root@test 10:31:54>select * from tmp_table;      
+--------+-------+      
| name | value |      
+--------+-------+      
| aaaaaa | 10 |      
+--------+-------+      
row in set (0.00 sec)      


session2      
root@test 10:20:13> CREATE TEMPORARY TABLE tmp_table (name VARCHAR(10) NOT NULL,value INTEGER NOT NULL);      
Query OK, 0 rows affected (0.02 sec)      


root@test 10:30:39>insert into tmp_table values ('bbbbbbb',10);      
Query OK, 1 row affected (0.01 sec)      


root@test 10:31:33>select * from tmp_table;      
+---------+-------+      
| name | value |      
+---------+-------+      
| bbbbbbb | 10 |      
+---------+-------+      
row in set (0.00 sec)      


root@test 10:31:43>exit      
Bye      
[1 Single:MS-Master db152011.sqa.cm6: mysql ~ ]      
$ mysql -uroot test      
root@test 10:32:17>select * from tmp_table;      
ERROR 1146 (42S02): Table 'test.tmp_table' doesn't exist      
root@test 10:32:22>      
root@test 10:32:23>      

1. 建立的表的名字能夠同樣 

2. 表結構和數據都放在內存中
3. 會話消失表結構和數據都消失
4. 能夠建立索引,刪除索引
5. 主庫建立的表,備庫查不到,
6. show tables 看不到表

使用內存表須要注意的事項

1. 內存表須要本身delete數據或者drop表;須要drop權限,這點比較危險

2. 內存表的表結構是保存在磁盤上的,若是多個session使用同一個表名,會存在衝突;若是不須要使用表名,若是使用一次都須要建立表結構,到時候會有不少小文件存在,不利於db的維護,dba清理表也有風險;

基於以上不適合用內存表

1. 臨時表是會話級別的,即便多個session建立的表名同樣,都相互不影響

2. 會話消失,全部的都消失,這點很不利於應用排查問題

另外這兩個都須要消耗額外的內存空間,雖然db端能夠忍受,可是不太可控;DB端還有這個參數:

max_tmp_tables 一個客戶能同時保持打開的臨時表的最大數量,這個值默認32,能夠根據須要調整此值


 
 
 
 





About Me

.............................................................................................................................................

● 本文做者:小麥苗,部份內容整理自網絡,如有侵權請聯繫小麥苗刪除

● 本文在itpub(http://blog.itpub.net/26736162/abstract/1/)、博客園(http://www.cnblogs.com/lhrbest)和我的微信公衆號(xiaomaimiaolhr)上有同步更新

● 本文itpub地址:http://blog.itpub.net/26736162/abstract/1/

● 本文博客園地址:http://www.cnblogs.com/lhrbest

● 本文pdf版、我的簡介及小麥苗雲盤地址:http://blog.itpub.net/26736162/viewspace-1624453/

● 數據庫筆試面試題庫及解答:http://blog.itpub.net/26736162/viewspace-2134706/

● DBA寶典今日頭條號地址:http://www.toutiao.com/c/user/6401772890/#mid=1564638659405826

.............................................................................................................................................

● QQ羣號:230161599(滿)、618766405

● 微信羣:可加我微信,我拉你們進羣,非誠勿擾

● 聯繫我請加QQ好友646634621,註明添加原因

● 於 2017-12-01 09:00 ~ 2017-12-31 22:00 在魔都完成

● 文章內容來源於小麥苗的學習筆記,部分整理自網絡,如有侵權或不當之處還請諒解

● 版權全部,歡迎分享本文,轉載請保留出處

.............................................................................................................................................

小麥苗的微店https://weidian.com/s/793741433?wfr=c&ifr=shopdetail

小麥苗出版的數據庫類叢書http://blog.itpub.net/26736162/viewspace-2142121/

.............................................................................................................................................

使用微信客戶端掃描下面的二維碼來關注小麥苗的微信公衆號(xiaomaimiaolhr)及QQ羣(DBA寶典),學習最實用的數據庫技術。

   小麥苗的微信公衆號      小麥苗的DBA寶典QQ羣2     《DBA筆試面寶典》讀者羣       小麥苗的微店

.............................................................................................................................................

ico_mailme_02.png
DBA筆試面試講解羣
《DBA寶典》讀者羣 歡迎與我聯繫




來自 「 ITPUB博客 」 ,連接:http://blog.itpub.net/26736162/viewspace-2149312/,如需轉載,請註明出處,不然將追究法律責任。

相關文章
相關標籤/搜索