偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

游標(biāo)腳本性能問(wèn)題詳解之案例實(shí)踐篇

數(shù)據(jù)庫(kù) SQL Server 數(shù)據(jù)庫(kù)運(yùn)維
關(guān)系數(shù)據(jù)庫(kù)中的操作會(huì)對(duì)整個(gè)行集起作用。由 SELECT 語(yǔ)句返回的行集包括滿足該語(yǔ)句的 WHERE 子句中條件的所有行。這種由語(yǔ)句返回的完整行集稱為結(jié)果集。應(yīng)用程序并不總能將整個(gè)結(jié)果集作為一個(gè)單元來(lái)有效地處理。這些應(yīng)用程序需要一種機(jī)制以便每次處理一行或一小部分行。游標(biāo)不僅可提供這種機(jī)制,而且是對(duì)結(jié)果集的一種擴(kuò)展。

游標(biāo)類型對(duì)性能影響的實(shí)例。下面的兩個(gè)游標(biāo)腳本分別創(chuàng)建并執(zhí)行了dynamic和fast forward only兩種類型的游標(biāo)。

知識(shí)補(bǔ)充:

關(guān)系數(shù)據(jù)庫(kù)中的操作會(huì)對(duì)整個(gè)行集起作用。由 SELECT 語(yǔ)句返回的行集包括滿足該語(yǔ)句的 WHERE 子句中條件的所有行。這種由語(yǔ)句返回的完整行集稱為結(jié)果集。應(yīng)用程序并不總能將整個(gè)結(jié)果集作為一個(gè)單元來(lái)有效地處理。這些應(yīng)用程序需要一種機(jī)制以便每次處理一行或一小部分行。游標(biāo)不僅可提供這種機(jī)制,而且是對(duì)結(jié)果集的一種擴(kuò)展。

游標(biāo)通過(guò)執(zhí)行以下操作來(lái)擴(kuò)展結(jié)果集處理:

  1. 允許定位在結(jié)果集的特定行。
  2. 從結(jié)果集的當(dāng)前位置檢索一行或一部分行。
  3. 支持對(duì)結(jié)果集中當(dāng)前位置的行進(jìn)行數(shù)據(jù)修改。
  4. 為由其他用戶對(duì)顯示在結(jié)果集中的數(shù)據(jù)庫(kù)數(shù)據(jù)所做的更改提供不同級(jí)別的可見(jiàn)性支持。

不理想的游標(biāo)類型:(dynamic游標(biāo))

  1. declare @p1 int  set @p1=NULL    
  2. declare @p2 int  set @p2=0    
  3. declare @p5 int  set @p5=4098  
  4. declare @p6 int  set @p6=8193    
  5. declare @p7 int  set @p7=0    
  6.  
  7. exec sp_cursorprepexec @p1 output,@p2 output,N'@P1 varchar(30),@P2 varchar(15)',  
  8. N'  
  9. SELECT       T1.CONFLICT_ID  
  10. FROM         dbo.S_AUDIT_ITEM T1              
  11. LEFT OUTER JOIN dbo.S_USER T2   
  12. ON T1.USER_ID = T2.PAR_ROW_ID      
  13. WHERE  ((T1.BC_BASE_TBL = @P1)    
  14. AND  (T1.RECORD_ID = @P2))      
  15. ORDER BY  T1.OPERATION_DT DESC    
  16. OPTION (FAST 40)  
  17. ',  
  18. @p5 output,@p6 output,@p7 output,'1-10350J','S_PARTY'    
  19.  
  20. print 'fetch' 
  21. exec sp_cursorfetch @p2,2,4,1    
  22.  
  23. exec sp_cursorclose @p2 

理想的游標(biāo)類型(fast forward only游標(biāo))

  1. declare @p1 int  set @p1=NULL    
  2. declare @p2 int  set @p2=0    
  3. declare @p5 int  set @p5=4112  
  4. declare @p6 int  set @p6=8193    
  5. declare @p7 int  set @p7=0    
  6.  
  7. exec sp_cursorprepexec @p1 output,@p2 output,N'@P1 varchar(30),@P2 varchar(15)',  
  8. N'  
  9. SELECT       T1.CONFLICT_ID  
  10. FROM         dbo.S_AUDIT_ITEM T1              
  11. LEFT OUTER JOIN dbo.S_USER T2   
  12. ON T1.USER_ID = T2.PAR_ROW_ID      
  13. WHERE  ((T1.BC_BASE_TBL = @P1)    
  14. AND  (T1.RECORD_ID = @P2))      
  15. ORDER BY  T1.OPERATION_DT DESC    
  16. OPTION (FAST 40)  
  17. ',  
  18. @p5 output,@p6 output,@p7 output,'S_SRV_REQ','1-WUQTM6'    
  19.  
  20. select @p1, @p2, @p5, @p6, @p7  
  21.  
  22. print '2' 
  23. exec sp_cursorfetch @p2,2,1,1    
  24. print '3' 
  25. exec sp_cursorclose @p2 

注:腳本中用到的和游標(biāo)有關(guān)的存儲(chǔ)過(guò)程,請(qǐng)參考:http://jtds.sourceforge.net/apiCursors.html#_sp_cursorprepexec

一、如何解讀游標(biāo)的類型

  1. sp_cursorprepexec [@handle =] statement_handle OUTPUT,  
  2.      [@cursor =] cursor_handle OUTPUT,  
  3.      [@paramdef =] N'parameter_name data_type, [,...n]'   
  4.      [@stmt =] N'stmt',  
  5.      [, [@scrollopt =] scroll_options OUTPUT]  
  6.      [, [@ccopt =] concurrency_options OUTPUT]  
  7.      [, [@rowcount =] rowcount OUTPUT]  
  8.  
  9. @scrollopt  

 

[@ccopt

 

@p5=4098 轉(zhuǎn)成16進(jìn)制就是1002,對(duì)應(yīng)的游標(biāo)類型為Parameterized query + Dynamic cursor

@p5=4112 轉(zhuǎn)成16進(jìn)制就是1010,對(duì)應(yīng)的游標(biāo)類型為Parameterized query + Fast forward-only cursor

問(wèn)題的現(xiàn)象是,左邊的游標(biāo)類型下,該腳本執(zhí)行時(shí)間遠(yuǎn)大于右邊的游標(biāo)類型。

#p#

二、如何比較兩個(gè)不同執(zhí)行計(jì)劃的優(yōu)劣

在繼續(xù)以下內(nèi)容之前,這里要介紹一些查看和比較語(yǔ)句執(zhí)行計(jì)劃的知識(shí)。通常情況下,我們從management studio中輸出圖形界面的執(zhí)行計(jì)劃進(jìn)行直觀的比較,查看每個(gè)表用的訪問(wèn)方式,使用index還是table scan,使用了哪個(gè)index,表和表之間使用的join 方式有什么不一樣。但是如果是一個(gè)復(fù)雜的語(yǔ)句,在不同的數(shù)據(jù)庫(kù)上使用了不同的執(zhí)行計(jì)劃,對(duì)于同樣表的訪問(wèn),使用了不同的index,如何比較哪種執(zhí)行計(jì)劃更加優(yōu)化呢?比較整個(gè)語(yǔ)句的執(zhí)行時(shí)間是一種方法,但是這個(gè)比較的結(jié)果并不準(zhǔn)確。語(yǔ)句的執(zhí)行時(shí)間很容易受到其他外在因素的影響:

1. 不同機(jī)器上CPU,memory和disk的性能會(huì)影響執(zhí)行時(shí)間。

2. 測(cè)試的時(shí)候有沒(méi)有其他人在使用同樣的數(shù)據(jù)造成阻塞

3. 其他人堆數(shù)據(jù)庫(kù)的使用占用了系統(tǒng)資源

以上這些原因都有可能影響的語(yǔ)句的執(zhí)行時(shí)間,從而影響到我們對(duì)語(yǔ)句性能結(jié)果的比較。因此我們不能把語(yǔ)句的執(zhí)行時(shí)間作為衡量語(yǔ)句性能的標(biāo)準(zhǔn)。

這里介紹一種比較語(yǔ)句cost的方法。我們對(duì)于語(yǔ)句cost的衡量,主要是通過(guò)比對(duì)語(yǔ)句總的logical reads.

我們可以通過(guò)在management studio里的query window 執(zhí)行”set statistics io on” ,在當(dāng)前窗口中對(duì)所有執(zhí)行的語(yǔ)句輸出信息:

  1. set statistics io on 
  2. select * from dbo.test_TicketFact  
  3. set statistics io on 

執(zhí)行語(yǔ)句兩次,以消除physical reads和read-ahead reads的影響。

輸出的結(jié)果如下:

  1. (320 row(s) affected)  
  2. Table 'test_TicketFact'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.  

這里打印出來(lái)了語(yǔ)句中訪問(wèn)過(guò)的table的訪問(wèn)次數(shù),總共的logical reads,physical reads等信息

這里我們需要關(guān)注的是logic reads的值,這個(gè)值實(shí)際上決定了對(duì)于IO和DISK以及內(nèi)存的消耗。當(dāng)語(yǔ)句是第一次執(zhí)行,我們會(huì)看到physical reads的數(shù)字,以,而當(dāng)語(yǔ)句第二次執(zhí)行的時(shí)候,這些數(shù)據(jù)已經(jīng)被讀到memory里面了,因此我們會(huì)看到physical read和read-ahead reads都變?yōu)?,而logical reads的值就變成了語(yǔ)句所有使用的data的量。

為什么logic reads是我們需要關(guān)注的值呢?因?yàn)閘ogic reads決定了語(yǔ)句要訪問(wèn)數(shù)據(jù)的量。如果我們的系統(tǒng)瓶頸在IO上,一旦語(yǔ)句需要訪問(wèn)的數(shù)據(jù)從內(nèi)存里面清除,這個(gè)語(yǔ)句原本所有的logic reads會(huì)全部轉(zhuǎn)為physical reads.因此那些大量使用logic reads就是可能導(dǎo)致大量physical reads的元兇。如果我們的bottleneck是CPU,這些做大量logical reads的語(yǔ)句同樣有可能導(dǎo)致大量的memory 讀,而讀memory是需要消耗CPU資源的。因此,無(wú)論是CPU,memory還是DISK的瓶頸,那些做大量logical reads的語(yǔ)句都非常可能是造成問(wèn)題的原因。

由以上內(nèi)容,我們可以得出結(jié)論,語(yǔ)句的性能好壞,取決與這個(gè)語(yǔ)句做了多少logical reads.因此,如果同樣的語(yǔ)句,使用了不同的執(zhí)行計(jì)劃,那么總的logical reads低的那個(gè)執(zhí)行計(jì)劃就是相對(duì)優(yōu)化的。

#p#

三、分析本案例中兩種游標(biāo)的執(zhí)行計(jì)劃

現(xiàn)在我們回到需要研究的腳本,在這里,語(yǔ)句是一樣的,不同的只是游標(biāo)的類型。不同的執(zhí)行時(shí)間說(shuō)明很可能這個(gè)語(yǔ)句使用了不同的執(zhí)行計(jì)劃?,F(xiàn)在問(wèn)題變成了,同樣語(yǔ)句使用了不同的執(zhí)行計(jì)劃,得到了不同的執(zhí)行時(shí)間。我們首先從”set statistics io on” 的結(jié)果入手:

1.左邊使用dynamic游標(biāo)有大量的邏輯讀,情況如下:

  1. Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.  
  2. Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.  
  3. Table 'S_AUDIT_ITEM'. Scan count 1, logical reads 9770695, physical reads 0, read-ahead reads 1, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.  

2.而右邊使用fast forward only游標(biāo)只有三次邏輯讀,情況為:

  1. Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.  
  2. Table 'Worktable'. Scan count 0, logical reads 0, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.  
  3. Table 'S_AUDIT_ITEM'. Scan count 1, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0. 

從這里輸出的結(jié)果的區(qū)別,說(shuō)明了在table S_AUDIT_ITEM上SQL Server使用了不同的訪問(wèn)方式

接下來(lái)我們分析兩個(gè)腳本的執(zhí)行計(jì)劃:

1. dynamic游標(biāo)對(duì)應(yīng)的不理想的執(zhí)行計(jì)劃中,SQL Server選擇了索引掃描(index scan)及索引S_AUDIT_ITEM_M4來(lái)查閱S_AUDIT_ITEM表。因此我們會(huì)在這里看到大量的IO。

 

這個(gè)索引掃描實(shí)際上訪問(wèn)了整張表的數(shù)據(jù)。

2.而fast forward only游標(biāo)對(duì)應(yīng)的理想的執(zhí)行計(jì)劃中,SQL Server選擇的是索引查找(index seek)及索引S_AUDIT_ITEM_M3來(lái)查閱S_AUDIT_ITEM表。所以我們只看到3個(gè)邏輯讀。索引S_AUDIT_ITEM_M3包含4個(gè)列,第一個(gè)列是RECORD_ID。另外,在語(yǔ)句中,有WHERE條件T1.RECORD_ID=@P2

 

#p#

四、嘗試解決問(wèn)題

首先我們嘗試更新統(tǒng)計(jì)信息:UPDATE STATISTICS ON S_AUDIT_ITEM WITH FULLSCAN,但是這個(gè)操作在此問(wèn)題案例中沒(méi)有作用。

從以上的分析中,我們已經(jīng)發(fā)現(xiàn),如果使用index S_AUDIT_ITEM_M3訪問(wèn)S_AUDIT_ITEM表,得到的執(zhí)行計(jì)劃非常好,我們可以直接用index hint來(lái)解決這個(gè)問(wèn)題:

  1. declare @p1 int set @p1=NULL 
  2.  
  3.   declare @p2 int set @p2=0  
  4.  
  5.   declare @p5 int set @p5=4098  
  6.  
  7.   declare @p6 int set @p6=8193  
  8.  
  9.   declare @p7 int set @p7=0  
  10.  
  11.   exec sp_cursorprepexec @p1 output,@p2 output,N'@P1 varchar(30),@P2 varchar(15)',  
  12.  
  13.   N'  
  14.  
  15.   SELECT T1.CONFLICT_ID  
  16.  
  17.   FROM dbo.S_AUDIT_ITEM T1 with (INDEX=S_AUDIT_ITEM_M3) /* 解決方案2 */  
  18.  
  19.   LEFT OUTER JOIN dbo.S_USER T2  
  20.  
  21.   ON T1.USER_ID = T2.PAR_ROW_ID  
  22.  
  23.   WHERE ((T1.BC_BASE_TBL = @P1)  
  24.  
  25.   AND (T1.RECORD_ID = @P2))  
  26.  
  27.   ORDER BY T1.OPERATION_DT DESC 
  28.  
  29.   OPTION (FAST 40)  
  30.  
  31.   ',  
  32.  
  33.   @p5 output,@p6 output,@p7 output,'1-10350J','S_PARTY' 
  34.  
  35.   print 'fetch' 
  36.  
  37.   exec sp_cursorfetch @p2,2,4,1  
  38.  
  39.   exec sp_cursorclose @p2  
  40.  

 

責(zé)任編輯:艾婧 來(lái)源: ITPUB
相關(guān)推薦

2011-04-06 09:30:29

游標(biāo)腳本性能問(wèn)題

2011-04-07 11:02:52

游標(biāo)

2010-05-26 18:08:30

Linux性能監(jiān)控

2015-09-16 13:54:30

Android性能優(yōu)化渲染

2015-09-16 14:37:50

Android性能優(yōu)化運(yùn)算

2015-09-16 15:48:55

Android性能優(yōu)化電量

2011-03-02 11:25:10

vsftpd配置

2012-09-10 09:39:31

Hadoop成功部署案例eBay

2023-07-10 16:18:18

性能優(yōu)化開(kāi)發(fā)

2010-02-07 13:55:12

萬(wàn)兆交換機(jī)

2018-09-03 09:22:25

監(jiān)控服務(wù)器性能

2010-05-26 18:40:54

Linux性能監(jiān)控

2011-04-18 10:16:30

WEB高性能

2010-05-26 18:21:04

Linux性能監(jiān)控

2010-05-26 18:31:51

Linux性能監(jiān)控

2011-11-08 21:47:37

Linux 監(jiān)控 IO

2020-03-17 09:21:20

MariaDBSpider存儲(chǔ)

2012-06-15 10:13:03

2011-07-22 09:50:34

云服務(wù)云計(jì)算

2022-05-26 10:12:21

前端優(yōu)化測(cè)試
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)