qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

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

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

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

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

          1. ALTER FUNCTION [dbo].[GetFrame_CustomerSerch]  
          2. (      
          3.     -- Add the parameters for the function here 
          4.     @WorkNo varchar(38)  
          5.     ,@SerchChar varchar(500)  
          6. )  
          7. RETURNS TABLE   
          8. AS 
          9. RETURN   
          10. (  
          11.     -- Add the SELECT statement with parameter references here 
          12.     select a.GUID,a.CustomerName,a.CustomerIDcard,a.CustomerPhone,a.CustomerMobile from 
          13.     (  
          14.    --具體子查詢略 
          15.     )  
          16.     ) a union all 
          17.     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  
          18.     --where a.WorkNo=@WorkNo 
          19.     WHERE a.WorkNo IN 
          20.     (  
          21. --具體子查詢略 
          22.     )  
          23.     )

            這個語句放在PDF.NET數據開發框架的SQL-MAP文件中,開始還以為是框架引起的,將這個語句直接在查詢分析器中查詢,仍然很慢。

            將GetFrame_CustomerSerch 中的SQL語句提取出來,直接加上Top查詢,只需要6秒,快了N倍:

          1. declare @WorkNo varchar(38)  
          2. declare @SerchChar varchar(500)  
          3. set @WorkNo='admin' 
          4. set @SerchChar='1' 
          5. select top 20 a.GUID,a.CustomerName,a.CustomerIDcard,a.CustomerPhone,a.CustomerMobile from 
          6.  (  
          7.   --具體子查詢略 
          8.  )  
          9.  ) a union all 
          10.  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  
          11.    
          12.  WHERE a.WorkNo IN 
          13.  (  
          14.  --具體子查詢略 
          15.  )

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

            我分析可能有如下原因:

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

            2、雖說該表值函數使用了“表變量”,它是內存中的,但如果這個“表”結果很大,很有可能內存放不下(并非還有物理內存就會將結果放到物理內存中,數據庫自己還會有保留的,會給其它查詢預留一定的內存空間),使用虛擬內存,而虛擬內存實際上就是磁盤頁面文件,當記錄太多就會發生頻繁的頁面交換,從而導致這個查詢效率非常低。

            看來,“表值函數”也不是傳說中的那么好,不知道大家是怎么認為的。

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

          posted on 2012-01-20 09:58 順其自然EVO 閱讀(352) 評論(1)  編輯  收藏

          評論

          # re: 分析TOP語句放到表值函數外,效率異常低下的原因 2013-03-21 15:25 393489589

          加我qq?393489589。。我也遇到你同樣的問題了。

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


          我的是一個存儲函數。情況和你這一模一樣  回復  更多評論   


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2012年1月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 义马市| 邯郸县| 长葛市| 元江| 桃园县| 宁远县| 迁西县| 天等县| 西青区| 盖州市| 皮山县| 怀柔区| 鱼台县| 丹寨县| 搜索| 富蕴县| 长阳| 通辽市| 高阳县| 宝应县| 康乐县| 拉萨市| 临清市| 柘城县| 常熟市| 浮山县| 中西区| 泰安市| 天气| 南部县| 全椒县| 奇台县| 嘉峪关市| 德庆县| 镇原县| 右玉县| 西乌珠穆沁旗| 麻江县| 民乐县| 正宁县| 壶关县|