比較 Cursor 的執行狀況

Ellie 和 Abby 提了一個有趣的問題,因為 Oracle 對 SQL Server 的存取會透過 Cursor,而針對 table 與 view 的 cursor 查詢,是否有效能差異?

簡單實驗如下:

use tempdb
create table tb(c1 int identity primary key,c2 varchar(100) default(‘Hello’),c3 datetime2(0) default(getdate()))
insert tb default values
go
insert tb(c2) select c2 from tb
go 20

create view vw
as
select top(10000) * from tb order by c1
go

declare @p1 int,@p2 int,@p5 int=1,@p6 int=1,@p7 int=1000000
exec sp_cursorprepexec @p1 output,@p2 output,NULL,N’select * from tb’, @p5 output,@p6 output,@p7 output
select @p1,@p2,@p5,@p6,@p7
set statistics io on
set statistics time on
exec sp_cursorfetch @p2,2,1,100
set statistics io off
set statistics time off

–觀察 cursor
declare @cur cursor
exec sp_cursor_list @cur output,3 –local 和 global
fetch @cur
/*
model:smallint  
1 = 不區分 (或靜態) 
2 = 索引鍵集 
3 = 動態 
4 = 向前快轉
*/
DEALLOCATE @cur

go

declare @p1 int,@p2 int,@p5 int=1,@p6 int=1,@p7 int=1000000
exec sp_cursorprepexec @p1 output,@p2 output,NULL,N’select * from vw’, @p5 output,@p6 output,@p7 output
select @p1,@p2,@p5,@p6,@p7
set statistics io on
set statistics time on
exec sp_cursorfetch @p2,2,1,100
set statistics io off
set statistics time off
–觀察 cursor
declare @cur cursor
exec sp_cursor_list @cur output,3 –local 和 global
fetch @cur
/*
model:smallint  
1 = 不區分 (或靜態) 
2 = 索引鍵集 
3 = 動態 
4 = 向前快轉
*/
DEALLOCATE @cur

就我實驗的結果,兩者雖然開的 Cursor Type 相同,都是 Keyset:

clip_image001

但 Keyset type 的 Cursor 在跑的時候,會參照開 Cursor 時的定義,所以會有效能的差異

clip_image002

換句話說,View 要寫得有效率才好,畢竟 View 有可能有欄位計算定義,而不僅是查詢資料表欄位,所以執行計畫需要照 View 來做。但 Order by 一定不是一個有效的語法…

若不是整個資料表都要轉到 Oracle,我想透過 View 是比較好,直接取 table 有可能全資料表都過去 Oracle 了,但寫 View 的語法要小心…

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 變更 )

Twitter picture

You are commenting using your Twitter account. Log Out / 變更 )

Facebook照片

You are commenting using your Facebook account. Log Out / 變更 )

Google+ photo

You are commenting using your Google+ account. Log Out / 變更 )

連結到 %s

%d 位部落客按了讚: