Ⅰ sql Server 表變數和臨時表的區別
臨時表
臨時表與永久表相似,只是它的創建是在Tempdb中,它只有在一個資料庫連接結束後或者由SQL命令DROP掉,才會消失,否則就會一直存在。臨時表在創建的時候都會產生SQL Server的系統日誌,雖它們在Tempdb中體現,是分配在內存中的,它們也支持物理的磁碟,但用戶在指定的磁碟里看不到文件。
臨時表分為本地和全局兩種,本地臨時表的名稱都是以「#」為前綴,只有在本地當前的用戶連接中才是可見的,當用戶從實例斷開連接時被刪除。全局臨時表的名稱都是以「##」為前綴,創建後對任何用戶都是可見的,當所有引用該表的用戶斷開連接時被刪除。
臨時表可以創建索引,也可以定義統計數據,所以可以用數據定義語言(DDL)的聲明來阻止臨時表添加的限制,約束,並參照完整性,如主鍵和外鍵約束。比如來說,我們現在來為#News表欄位NewsDateTime來添加一個默認的GetData()當前日期值,並且為News_id添加一個主鍵。
臨時表在創建之後可以修改許多已定義的選項,包括:
1)添加、修改、刪除列。例如,列的名稱、長度、數據類型、精度、小數位數以及為空性均可進行修改,只是有一些限制而已。
2)可添加或刪除主鍵和外鍵約束。
3)可添加或刪除 UNIQUE 和 CHECK 約束及 DEFAULT 定義(對象)。
4)可使用 IDENTITY 或 ROWGUIDCOL 屬性添加或刪除標識符列。雖然 ROWGUIDCOL 屬性也可添加至現有列或從現有列刪除,但是任何時候在表中只能有一列可具有該屬性。
5)表及表中所選定的列已注冊為全文索引。
Ⅱ SQL Server 表變數和臨時表的區別
臨時表、表變數的比較
1、臨時表
臨時表包括:以#開頭的局部臨時表,以##開頭的全局臨時表。
a、存儲
不管是局部臨時表,還是全局臨時表,都會放存放在tempdb資料庫中。
b、作用域
局部臨時表:對當前連接有效,只在創建它的存儲過度、批處理、動態語句中有效,類似於C語言中局部變數的作用域。
全局臨時表:在所有連接對它都結束引用時,會被刪除,對創建者來說,斷開連接就是結束引用;對非創建者,不再引用就是結束引用。
但最好在用完後,就通過drop table 語句刪除,及時釋放資源。
c、特性
與普通的表一樣,能定義約束,能創建索引,最關鍵的是有數據分布的統計信息,這樣有利於優化器做出正確的執行計劃,但同時它的開銷和普通的表一樣,一般適合數據量較大的情況。
有一個非常方便的select ... into 的用法,這也是一個特點。
2、表變數
a、存儲
表變數存放在tempdb資料庫中。
b、作用域
和普通的變數一樣,在定義表變數的存儲過程、批處理、動態語句、函數結束時,會自動清除。
c、特性
可以有主鍵,但不能直接創建索引,也沒有任何數據的統計信息。表變數適合數據量相對較小的情況。
必須要注意的是,表變數不受事務的約束,
Ⅲ sql server中的臨時表與普通表有什麼區別
作用域不同,當你關閉sql連接的時候 臨時表就會 自動刪除,普通表不會
1、創建方法:
方法一:
create table TempTableName
或
select [欄位1,欄位2,...,] into TempTableName from table
方法二:
create table tempdb.MyTempTable(Tid int)
說明:
(1)、臨時表其實是放在資料庫tempdb里的一個用戶表;
(2)、TempTableName必須帶「#」,「#"可以是一個或者兩個,以#(局部)或##(全局)開頭的表,這種表在會話期間存在,會話結束則自動刪除;
(3)、如果創建時不以#或##開頭,而用tempdb.TempTable來命名它,則該表可在資料庫重啟前一直存在。
2、手動刪除
drop table TempTableName
普通表和臨時表的區別只是表名開頭無 "#"
Ⅳ sql臨時表多大時會影響性能
sql臨時表為20G時會影響性能。根據查詢相關公開信息顯示,臨時表會和普通文件一樣占據一定內存,影響系統工作效率,臨時表是建立在系統臨時文件夾中的表,使用得當,可以像普通表一樣進行各種操作,在退出時自動被釋放。
Ⅳ sql 臨時表記錄數限制問題
臨時表也是存儲在硬碟上的,沒有限制的
Ⅵ 技術分享 | 淺談 MySQL 的臨時表和臨時文件
本文內容來源於對客戶的三個問題的思考:
以下測試都是在 MySQL 8.0.21 版本中完成,不同版本可能存在差異,可自行測試;
臨時表和臨時文件都是用於臨時存放數據集的地方;
一般情況下,需要臨時存放在臨時表或臨時文件中的數據集應該符合以下特點:
從臨時表|臨時文件產生的主觀性來看,分為2類:
用戶創建臨時表:
-- 用戶創建臨時表(只有創建臨時表的會話才能查看其創建的臨時表的內容)
注意:
可以創建和普通表同名臨時表,其他會話可以看到普通表(因為看不到其他會話創建的臨時表);
創建臨時表的會話會優先看到臨時表;
-- 同名表的創建的語句如下
當存在同名的臨時表時,會話都是優先處理臨時表(而不是普通表),包括:select、update、delete、drop、alter 等操作;
查看用戶創建的臨時表:
任何 session 都可以執行下面的語句;
查看用戶創建的當前 active 的臨時表(不提供 optimizer 使用的內部 InnoDB 臨時表信息)
注意
用戶創建的臨時表,表名為t1,
但是通過 INNODB_TEMP_TABLE_INFO 查看到的臨時表的 NAME 是#sql開頭的名字,例如:#sql45aa_7c69_2 ;
另外 information_schema.tables 表中是不會記錄臨時表的信息的。
用戶創建的臨時表的回收:
用戶創建的臨時表的其他信息&參數:
會話臨時表空間存儲 用戶創建的臨時表和優化器 optimizer 創建的內部臨時表(當磁碟內部臨時表的存儲引擎為 InnoDB 時);
innodb_temp_tablespaces_dir 變數定義了創建 會話臨時表空間的位置,默認是數據目錄下的#innodb_temp 目錄;
文件類似temp_[1-20].ibt ;
查看會話臨時表空間的元數據:
用戶創建的臨時表刪除後,其佔用的空間會被釋放(temp_[1-20].ibt文件會變小)。
在 MySQL 8.0.16 之前,internal_tmp_disk_storage_engine 變數定義了用戶創建的臨時表和 optimizer 創建的內部臨時表的引擎,可選 INNODB 和 MYISAM ;
從 MySQL 8.0.16 開始,internal_tmp_disk_storage_engine參數被移除,默認使用InnoDB存儲引擎;
innodb_temp_data_file_path 定義了用戶創建的臨時表使用的回滾段的存儲文件的相對路徑、名字、大小和屬性,該文件是全局臨時表空間(ibtmp1);
可以使用語句查詢全局臨時表空間的數據文件大小:
SQL 什麼時候產生臨時表|臨時文件呢?
需要用到臨時表或臨時文件的時候,optimizer 自然會創建使用(感覺是廢話,但是又覺得有道理=.=!);
(想像能力強的,可以牢記上面這句話;想像能力弱的,只能死記下面的 SQL 了。我也弱,此處有個疲憊的微笑😊)
下面列舉一些 server 在處理 SQL 時,可能會創建內部臨時表的 SQL :
SQL 包含 union | union distinct 關鍵字
SQL 中存在派生表
SQL 中包含 with 關鍵字
SQL 中的order by 和 group by 的欄位不同
SQL 為多表 update
SQL 中包含 distinct 和 order by 兩個關鍵字
我們可以通過下面兩種方式判斷 SQL 語句是否使用了臨時表空間:
# 如果 explain 的 Extra 列包含 Using temporary ,那麼說明會使用臨時空間,如果包含 Using filesort ,那麼說明會使用文件排序(臨時文件);
如果執行 SQL 後,表的 ID 列變為了show processlist 中的 id 列的值,那麼說明 SQL 語句使用了臨時表空間
SQL創建的內部臨時表的存儲信息:
SQL 創建內部臨時表時,優先選擇在內存中,默認使用 TempTable 存儲引擎(由參數 internal_tmp_mem_storage_engine 確定),
當 temptable 使用的內存量超過 temptable_max_ram 定義的大小時,
由 temptable_use_mmap 確定是使用內存映射文件的方式還是 InnoDB 磁碟內部臨時表的方式存儲數據
(temptable_use_mmap 參數在 MySQL 8.0.16 引入,MySQL 8.0.26 版本不推薦,後續應該會移除);
temptable_use_mmap 的功能將由MySQL 8.0.23 版本引入的 temptable_max_mmap 代替,
當 temptable_max_mmap=0 時,說明不使用內存映射文件,等價於 temptable_use_mmap=OFF ;
當 temptable_max_mmap=N 時,N為正整數,包含了 temptable_use_mmap=ON 以及聲明了允許為內存映射文件分配的最大內存量。
該參數的定義解決了這些文件使用過多空間的風險。
內存映射文件產生的臨時文件會存放於 tmpdir 定義的目錄中,在 TempTable 存儲引擎關閉或 mysqld 進程關閉時,回收空間;
當 SQL 創建的內部臨時表,選擇 MEMORY 存儲引擎時,如果內存中的臨時表變的太大,MySQL 將自動將其轉為磁碟臨時表;
其能使用的內存上限為 min(tmp_table_size,max_heap_table_size);
監控 TempTable 從內存和磁碟上分配的空間:
具體的欄位含義見:Section 27.12.20.10, 「Memory Summary Tables」.
監控內部臨時表的創建:
當在內存或磁碟上創建內部臨時表,伺服器會增加 Created_tmp_tables 的值;
當在磁碟上創建內部臨時表時,伺服器會增加 Created_tmp_disk_tables 的值,
如果在磁碟上創建了太多的內部臨時表,請考慮增加 tmp_table_size 和 max_heap_table_size 的值;
created_tmp_disk_tables 不計算在內存映射文件中創建的磁碟臨時表;
例外項:
臨時表/臨時文件一般較小,但是也存在需要大量空間的臨時表/臨時文件的需求:
因為這些例外項一般需要較大的空間,所以需要考慮是否要將其存放在獨立的掛載點上。
其他:
列出由失敗的 alter table 創建的隱藏臨時表,這些臨時表以#sql開頭,可以使用 drop table 刪除;
通過 lsof +L1 可以查看標識為 delete ,但還未釋放空間的文件。
如果想釋放這些 delete 狀態的文件,可以嘗試下面的方法(不推薦,後果自負):
普通的磁碟臨時表|臨時文件(一般需要較小的空間):
臨時表|臨時文件的一般所需的空間較小,會優先存放於內存中,若超過一定的大小,則會轉換為磁碟臨時表|臨時文件;
磁碟臨時表默認為 InnoDB 引擎,其存放在臨時表空間中,由 innodb_temp_tablespaces_dir 定義表空間的存放目錄,表空間文件類似:temp_[1-20].ibt ;MySQL 未定義 InnoDB 臨時表空間的最大使用上限;
當臨時表|臨時文件使用完畢後,會自動回收臨時表空間文件的大小;
innodb_temp_data_file_path 定義了用戶創建的臨時表使用的回滾段的存儲文件的相對路徑、名字、大小和屬性,該文件是全局臨時表空間(ibtmp1),該文件可以設置文件最大使用大小;
例外項(一般需要較大的空間):
load data local 語句,客戶端讀取文件並將其內容發送到伺服器,伺服器將其存儲在 tmpdir 參數指定的路徑中;
在 replica 中,回放 load data 語句時,需要將從 relay log 中解析出來的數據存儲在 slave_load_tmpdir(replica_load_tmpdir) 指定的目錄中,該參數默認和 tmpdir 參數指定的路徑相同;
需要 rebuild table 的在線 alter table 需要使用 innodb_tmpdir 存放排序磁碟排序文件,如果 innodb_tmpdir 未指定,則使用 tmpdir 的值;
若用戶判斷產生的臨時表|臨時文件一定會轉換為磁碟臨時表|臨時文件,那麼可以設置 set session big_tables=1;讓產生的臨時表|臨時文件直接存放在磁碟上;
對於需要較小空間的臨時表|臨時文件,MySQL 要麼將其存儲於內存,要麼放在統一的磁碟臨時表空間中,用完即釋放;
對於需要較大空間的臨時表|臨時文件,可以通過設置參數,將其存儲於單獨的目錄|掛載點;例如:load local data 語句或需要重建表的在線 alter table 語句,都有對應的參數設置其存放臨時表|臨時文件的路徑;
當前只有 innodb_temp_data_file_path 參數可以限制 用戶創建的臨時表使用的回滾段的存儲文件的大小,無其他參數可以限制臨時表|臨時文件可使用的磁碟空間;