分析TOP語句放到錶值函式外,效率異常低下的原因

2021-09-23 13:49:47 字數 2082 閱讀 2005

sqlserver的錶值函式是sqlserver 2005以來的新特性,由於它使用比較方便,就像乙個單獨的表一樣,在我們的系統中大量使用。有乙個獲取客戶資料的sqlserver 錶值函式,如果使用管理員登入,這個函式會返回150w行記錄,大概需要30秒左右,但如果將top語句放到錶值函式外,效率異常低下,需要約3分鐘:

select top 20  * from getframe_customerserch('admin','1')

下面是該儲存過程的定義:

alter function [dbo].[getframe_customerserch]  

(      

-- add the parameters for the function here 

@workno varchar(38)  

,@serchchar varchar(500)  

)  returns table   

as return   

(  -- add the select statement with parameter references here 

select a.guid,a.customername,a.customeridcard,a.customerphone,a.customermobile from 

(  --具體子查詢略 

)  ) a union all 

select b.guid,b.customername,b.customeridcard,b.customerphone,b.customermobile from wft_managercollectusers a left join wft_customer b on a.fundaccount=b.fundaccount  

--where a.workno=@workno 

where a.workno in 

(  --具體子查詢略 

)  )

這個語句放在pdf.net資料開發框架的sql-map檔案中,開始還以為是框架引起的,將這個語句直接在查詢分析器中查詢,仍然很慢。

將getframe_customerserch 中的sql語句提取出來,直接加上top查詢,只需要6秒,快了n倍:

declare @workno varchar(38)  

declare @serchchar varchar(500)  

set @workno='admin' 

set @serchchar='1' 

select top 20 a.guid,a.customername,a.customeridcard,a.customerphone,a.customermobile from 

(  --具體子查詢略 

)  ) a union all 

select b.guid,b.customername,b.customeridcard,b.customerphone,b.customermobile from wft_managercollectusers a left join wft_customer b on a.fundaccount=b.fundaccount  

where a.workno in 

(  --具體子查詢略 )

為什麼會有這麼大的差異?

我分析可能有如下原因:

1、在錶值函式外使用top或者其它條件,sqlserver 的查詢優化器無法針對此查詢進行優化,比如先返回所有記錄,然後再在臨時表中選取前面的20條記錄;

2、雖說該錶值函式使用了「表變數」,它是記憶體中的,但如果這個「表」結果很大,很有可能記憶體放不下(並非還有物理記憶體就會將結果放到物理記憶體中,資料庫自己還會有保留的,會給其它查詢預留一定的記憶體空間),使用虛擬記憶體,而虛擬記憶體實際上就是磁碟頁面檔案,當記錄太多就會發生頻繁的頁面交換,從而導致這個查詢效率非常低。

看來,「錶值函式」也不是傳說中的那麼好,不知道大家是怎麼認為的。

最近還遇到乙個怪異的問題,有乙個儲存過程,老是在系統執行1-2天後變得極其緩慢,但重新修改一下又很快了(只是加乙個空格之類),不知道大家遇到過沒有,什麼原因?

TOP語句放到錶值函式外,效率異常低下

在 系統中,有乙個獲取客戶資料的sqlserver 錶值函式,如果使用管理員登入,這個函式會返回150w行記錄,大概需要30秒左右,但如果將top語句放到錶值函式外,效率異常低下,需要約3分鐘 select top20 from getframe customerserch admin 1 將get...

表分析語句

exec dbms stats.gather schema stats ownname 使用者名稱 estimate percent 100,cascade true,degree 12 含 釋 ownname 填寫需要分析的使用者 該使用者下所有表都將被分析 estimate percent 分析...

多語句錶值函式

多語句錶值函式 多語句錶值函式可以看做是標量函式和內聯錶值函式的結合體。語法 create function 函式名 引數列表 returns 表變數名 table 表變數的字段定義 as begin sql語句 return end 練習 根據性別返回所有學生的學號,姓名,籍貫,數學成績,如果是女...