sqlserver 臨時表 表變數 CTE的比較

2022-02-16 18:01:36 字數 3213 閱讀 9546

1、臨時表

1.1 臨時表包括:以#開頭的區域性臨時表,以##開頭的全域性臨時表。 1.2 儲存不管是區域性臨時表,還是全域性臨時表,都會放存在tempdb資料庫中。 1.3 作用域區域性臨時表:對當前連線有效,只在建立它的儲存過程、批處理、動態語句中有效,類似於c#語言中區域性變數的作用域。全域性臨時表:在所有連線對它都結束引用時,會被刪除,對建立者來說,斷開連線就是結束引用;對非建立者,不再引用就是結束引用。但最好在用完後,就通過drop  table 語句刪除,及時釋放資源。 1.4 特性

和普通的表一樣,能定義約束,能建立索引,最關鍵的是有資料分布的統計資訊,這樣有利於優化器做出正確的執行計畫,但同時它的開銷和普通的表一樣,一般適合資料量較大的情況。有乙個非常方便的select ... into 的用法,這也是乙個特點。

1.5  

使用場景:

資料量小直接當做中間表使用,資料量較大可以通過優化提高查詢效率,對於複雜的查詢可以將中間結果放在臨時表中以固化執行計畫(專治執行計畫走錯)

2、表變數

2.1 儲存

表變數存放在tempdb資料庫中。

2.2 作用域

和普通的變數一樣,在定義表變數的儲存過程、批處理、動態語句、函式結束時,會自動清除。

2.3 特性

可以有主鍵,但不能直接建立索引,也沒有任何資料的統計資訊。

2.4 使用場景:小資料量(百條以內) 注意:表變數不受事務的約束,下面的demo會演示。

--demo 表變數

declare @tb table(col1 int primary key,col2 varchar(10))

begin tran

insert into @tb

select 1,'aa'

rollback tran

--雖然上面回滾了事務,但還是會返回1條記錄

select * from @tb

begin tran

update @tb

set col2= 'bb'

where col1 = 1

rollback tran

--返回的資料顯示,update操作成功,根本沒有回滾

select * from @tb

3、cte

3.1 內涵

cte,就是通用表表示式。

3.2 儲存

產生的資料一般儲存在記憶體,不會持久化儲存。

也可以持久化:

;with cte  

as (

select 1 as v,'aa' as vv

union all

select 2,'bb'

)

--把cte的資料儲存在tb_cte表

select * into tb_cte

from cte

select * from tb_cte;

--運用cte,刪除資料

;with cte_delete

as (

select * from tb_cte

)

delete from cte_delete where v = 1

--返回1條資料,另一條已刪除

select * from tb_cte

當然,在實際執行時,有些部分,比如假離線,會把資料儲存在tempdb的worktable、workfile中,另外,一些大的hash join和排序操作,也會把中間資料儲存在tempdb。

3.3 作用域

cte下第一條sql
3.4 使用場景

遞迴,sql邏輯化(重複的部分寫到cte裡面,能減少sql量,增加sql條理性和可讀性) 注意:sql邏輯化改寫並不能固定執行計畫(邏輯中間表,實際解析後還是乙個sql)
3.5 特性在同乙個語句中,一次定義,可以多次引用。也可以定義遞迴語句。其實,本質問題就是,乙個語句幾千行,語句太複雜了,sql server很難做出最優化的執行計畫,這確實難為sql server了,所以後來就把這個cte改為,每一小段語句,把結果集通過select into插入到臨時表中,因為臨時表是有統計資訊的,這樣最後關聯多個臨時表。對sql server而言,現在有了每個小的結果集的精確的統計資訊,那麼就自然能做出更為精確的執行計畫,執行效能自然上公升。

cte遞迴案例

--目的:通過傳入parentid(=5),返回該記錄的所有子節點資料

if object_id('digui','u') is not null drop table digui

create table digui(

id int,

parentid int

)insert into dbo.digui

( id, parentid )

select 4 ,0

union select 5 ,0

union select 7 ,0

union select 2 ,1

union select 8 ,5

union select 15 ,5

union select 9 ,7

union select 14 ,11

union select 30 ,15

union select 23 ,15

union select 41 ,18

union select 104, 23

union select 42 ,30

union select 39 ,30

union select 53 ,39

union select 67 ,39

union select 88 ,39

union select 107, 39

;with temp ( [id], [parentid])as(

select id, parentid from digui where [parentid] = 5

union all

select a.id, a.parentid

from digui a

inner join temp b on a.[parentid] = b.[id]

)select * from temp

sqlserver 臨時表 表變數 CTE的比較

1 臨時表 1.1 臨時表包括 以 開頭的區域性臨時表,以 開頭的全域性臨時表。1.2 儲存 不管是區域性臨時表,還是全域性臨時表,都會放存在tempdb資料庫中。1.3 作用域 區域性臨時表 對當前連線有效,只在建立它的儲存過程 批處理 動態語句中有效,類似於c 語言中區域性變數的作用域。全域性臨...

sqlserver 臨時表 表變數 CTE的比較

1 臨時表 1.1 臨時表包括 以 開頭的區域性臨時表,以 開頭的全域性臨時表。1.2 儲存不管是區域性臨時表,還是全域性臨時表,都會放存在tempdb資料庫中。1.3 作用域區域性臨時表 對當前連線有效,只在建立它的儲存過程 批處理 動態語句中有效,類似於c 語言中區域性變數的作用域。全域性臨時表...

T SQL系列 臨時表 表變數

臨時表 臨時表與永久表相似,只是它的建立是在tempdb中,它只有在乙個資料庫連線結束後或者由sql命令drop掉,才會消失,否則就會一直存在。臨時表在建立的時候都會產生sql server的系統日誌,雖它們在tempdb中體現,是分配在記憶體中的,它們也支援物理的磁碟,但使用者在指定的磁碟裡看不到...