36 臨時表和臨時表

2021-10-03 22:52:26 字數 2416 閱讀 4978

臨時表特點:

建表語法是create temporary table乙個臨時表只能被建立它的session訪問,對其他執行緒不可見。

臨時表和普通表可以同名。

同乙個session內有臨時表和普通表的時候,show crete語句、增刪改查訪問的是臨時表。

show tabls命令不顯示臨時表。

由於臨時表只能被建立它的 session 訪問,所以在這個 session 結束的時候,會自動刪除臨時表。也正是由於這個特性,臨時表就特別適合我們文章開頭的 join 優化這種場景,原因:

不同 session 的臨時表是可以重名的,如果有多個 session 同時執行 join 優化,不需要擔心表名重複導致建表失敗的問題。

不需要擔心資料刪除問題。如果使用普通表,在流程執行過程中客戶端發生了異常斷開,或者資料庫發生異常重啟,還需要專門來清理中間過程中生成的資料表。而臨時表由於會自動**,所以不需要這個額外的操作。

一般分庫分表的場景,就是要把乙個邏輯上的大表分散到不同的資料庫例項上。比如。將乙個大表 ht,按照字段 f,拆分成 1024 個分表,然後分布到 32 個資料庫例項上。如下圖所示:

一般等值查詢:

select v from ht where f=n;
以通過分表規則(比如,n%1024) 來確認需要的資料被放在了哪個分表上。這種語句只需要訪問乙個分表,是分庫分表方案最歡迎的語句形式了。

但是遇到複雜一點的語句:

select v from ht where k >= m order by t_modified desc limit 100;
只能到所有的分割槽中去查詢滿足條件的所有行,然後統一做 order by 的操作。這種情況下,有兩種比較常用的思路:

這種方式的優勢是處理速度快,拿到分庫的資料以後,直接在記憶體中參與計算。不過,這個方案的缺點也比較明顯:

需要的開發工作量比較大。我們舉例的這條語句還算是比較簡單的,如果涉及到複雜的操作,比如 group by,甚至 join 這樣的操作,對中間層的開發能力要求比較高;

對 proxy 端的壓力比較大,尤其是很容易出現記憶體不夠用和 cpu 瓶頸的問題。

流程:

create temporary table temp_t(id int primary key)engine=innodb;
在建立臨時表的時候,mysql 要給這個 innodb 表建立乙個 frm 檔案儲存表結構定義,還要有地方儲存表資料。

這個 frm 檔案放在臨時檔案目錄下,檔名的字尾是.frm,字首是「#sql 序列號」

而關於表中資料的存放方式,在不同的 mysql 版本中有著不同的處理方式:

至於為什麼不會重名:

在實現上,每個執行緒都維護了自己的臨時錶鏈表。這樣每次 session 內操作表的時候,先遍歷鍊錶,檢查是否有這個名字的臨時表,如果有就優先操作臨時表,如果沒有再操作普通表;在 session 結束的時候,對鍊表裡的每個臨時表,執行 「drop temporary table + 表名」操作。

臨時表的操作也會記錄到binlog,既然寫binlog,意味著備庫也會執行。

為什麼要記錄binlog的原因,demo:

create table t_normal(id int primary key, c int)engine=innodb;/*q1*/

create temporary table temp_t like t_normal;/*q2*/

insert into temp_t values(1,1);/*q3*/

insert into t_normal select * from temp_t;/*q4*/

以上如果不記錄臨時表的操作,那麼就會報錯「表 temp_t 不存在」。

如果binlog設定為binlog_format=row格式,那麼就不會記錄臨時表有關的語句,此時記錄的是這個操作的資料。即:write_row event 裡面記錄的邏輯是「插入一行資料(1,1)」。

通常備庫執行drop語句,一般是服務端修改過的,比如:

drop table `t_normal` /* generated by server */
「/* generated by server */」說明了這是乙個被服務端改寫過的命令。

因為假如真的是row格式,drop table t_normal, temp_t;是會報找不到臨時表的。

MySQL 36 內部臨時表

36.1 mysql中的兩種臨時表 通過create temporary table建立的臨時表,這種臨時表稱為外部臨時表。這種臨時表只對當前使用者可見,當前會話結束的時候,該臨時表會自動關閉。這種臨時表的命名與非臨時表可以同名。內部臨時表會被mysql自動建立並用來儲存某些操作的中間結果,通過ex...

Oracle的臨時表和MySQL的臨時表

最近在oracle遷移mysql過程中遇到了一些關於with as 語法的問題,但是在mysql中是沒有這樣的語法的,因為我使用了臨時表代替了 因此今天做了一些小總結,歡迎各位大佬指導。一 oracle with as語法 with tablename as select select 它在查詢之前...

mysql臨時表更新 MySql 臨時表

今天在專案中遇到乙個,當mysql的in語句中資料量很大時,建立乙個臨時表的例子。於是樓主整理了一下關於臨時表的知識,與大家分享一下 首先,臨時表只在當前連線可見,當關閉連線時,mysql會自動刪除表並釋放所有空間。因此在不同的連線中可以建立同名的臨時表,並且操作屬於本連線的臨時表。建立臨時表 cr...