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

游標腳本性能問題詳解之游標分類特點篇

數(shù)據(jù)庫 SQL Server 數(shù)據(jù)庫運維
從上篇游標腳本性能問題詳解之案例實踐篇兩個腳本執(zhí)行情況的對比中可以看出,游標的選擇對語句執(zhí)行的性能具有一定的影響。下面我們來進行一定的比較分析,并學(xué)習如何使用各種游標。

從上篇游標腳本性能問題詳解之案例實踐篇兩個腳本執(zhí)行情況的對比中可以看出,游標的選擇對語句執(zhí)行的性能具有一定的影響。

在SQL Server聯(lián)機叢書上列出了不止十種游標類型,但是所有游標都可以被劃到兩大類別:

1. 通過從***得到結(jié)果的臨時拷貝映像靜態(tài)進行

2. 每次fetch都通過動態(tài)進行且真正查閱表

STATIC、KEYSET、READ_ONLY和FAST_FORWARD屬于***大類,F(xiàn)ORWARD_ONLY、DYNAMIC和OPTIMISTIC屬于第二大類。

下面我們來進行一定的比較分析,并學(xué)習如何使用各種游標。在進行這部分之前,我們要引入另一個set statistics的方法: set statistics profile on

這個option會幫助我們打印出文本格式的執(zhí)行計劃和每一布的執(zhí)行統(tǒng)計信息。這個部分的執(zhí)行語句執(zhí)行計劃都是通過這個option打印的。

1. 首先,我們把游標腳本中的SQL語句抽取出來直接運行而不使用游標:

  1. SELECT       T1.*  
  2. FROM         dbo.S_AUDIT_ITEM T1              
  3. LEFT OUTER JOIN dbo.S_USER T2   
  4. ON T1.USER_ID = T2.PAR_ROW_ID      
  5. WHERE   T1.BC_BASE_TBL = 'S_PARTY' AND   T1.RECORD_ID = '1-10350J' 
  6. ORDER BY       T1.OPERATION_DT DESC  

執(zhí)行情況如下:邏輯讀15次,使用的是索引查找(index seek)

  1. Table 'S_USER'. Scan count 1, logical reads 260, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.  
  2. Table 'S_AUDIT_ITEM'. Scan count 1, logical reads 15, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.  

執(zhí)行計劃為:

  1. Rows                 Executes             StmtText                                                                                                   
  2. -------------------- -------------------- ---------------------------------------------------------------------------------------------------------  
  3. 4                    1                    SELECT  T1.*  FROM  dbo.S_AUDIT_ITEM T1                                                                                                                     
  4. LEFT OUTER JOIN dbo.S_USER T2                                                                                                                        
  5. ON T1.USER_ID = T2.PAR_ROW_ID                                                                                                                        
  6. WHERE   T1.BC_BASE_TBL = 'S_PARTY' AND   T1.RECORD_ID = '1-10350J'                                                                                 ORDER BY  T1.OPERATION_DT DESC            1    1    0      NULL         NULL                     
  7. 4                    1                      |--Sort(ORDER BY:([T1].[OPERATION_DT] DESC))                                                             
  8. 4                    1                           |--Nested Loops(Left Outer Join, WHERE:([testcursor].[dbo].[S_AUDIT_ITEM].[USER_ID] as [T1].[USER_  
  9. 4                    1                                |--Nested Loops(Inner Join, OUTER REFERENCES:([Uniq1002], [T1].[ROW_ID]) OPTIMIZED)            
  10. 4                    1                                |  |--Index Seek(OBJECT:([testcursor].[dbo].[S_AUDIT_ITEM].[S_AUDIT_ITEM_M3] AS [T1]), SEEK  
  11. 4                    4                                |  |--Clustered Index Seek(OBJECT:([testcursor].[dbo].[S_AUDIT_ITEM].[S_AUDIT_ITEM_P1] AS [  
  12. 66908                4                                |--Table Scan(OBJECT:([testcursor].[dbo].[S_USER] AS [T2]))     

2. 下面通過T-SQL語句打開一個游標。注意,這里創(chuàng)建的游標為dynamic類型,因為新聲明的游標默認類型為dynamic。。本文開頭使用的存儲過程是調(diào)用API游標的寫法,這里是用T-SQL語句打開游標,兩種寫法使用的游標類型和執(zhí)行的語句是完全一樣的。

  1. declare @CONFLICT_ID int 
  2. declare curTest cursor 
  3.  
  4. FOR 
  5.     SELECT   
  6.        T1.CONFLICT_ID  
  7.     FROM         dbo.S_AUDIT_ITEM T1              
  8.     LEFT OUTER JOIN dbo.S_USER T2  
  9.     ON T1.USER_ID = T2.PAR_ROW_ID      
  10.     WHERE      T1.BC_BASE_TBL = 'S_PARTY' AND   T1.RECORD_ID ='1-10350J'     
  11.     ORDER BY       T1.OPERATION_DT    
  12.  
  13. OPEN curTest  
  14. FETCH NEXT FROM curTest   
  15. INTO @CONFLICT_ID  
  16. CLOSE curTest  
  17.  
  18. deallocate curTest 

執(zhí)行情況為:邏輯讀明顯增多,使用索引掃描(index scan)

  1. Table 'Worktable'. Scan count 0, logical reads 3, physical reads 0, read-ahead reads 0, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.                 
  2. Table 'S_USER'. Scan count 1, logical reads 64, 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 3026834, physical reads 1292, read-ahead reads 5574, lob logical reads 0, lob physical reads 0, lob read-ahead reads 0.  

執(zhí)行計劃如下:

  1. Rows                 Executes             StmtText                                                                                                                          
  2. -------------------- -------------------- --------------------------------------------------------------------------------------------------------------------------------  
  3. 1                    1                    FETCH NEXT FROM curTest                                                                                                           
  4. INTO @CONFLICT_ID                                                                                                                                                           
  5. 1                    1                      |--Clustered Index Insert(OBJECT:(CWT), SET:([CWT].[COLUMN0] = [testcursor].[dbo].[S_AUDIT_ITEM].[ROW_ID] as   
  6. 1                    1                           |--Compute Scalar(DEFINE:([Expr1008]=CWT_ROWID()))                                                                         
  7. 1                1                                |--Nested Loops(Left Outer Join, WHERE:([testcursor].[dbo].[S_AUDIT_ITEM].[USER_ID] as   
  8. 1                    1                                     |--Nested Loops(Inner Join, OUTER REFERENCES:([Uniq1004], [T1].[ROW_ID]))                                        
  9. 1007751              1                                     |    |--Index Scan(OBJECT:([testcursor].[dbo].[S_AUDIT_ITEM].[S_AUDIT_ITEM_M4] AS     
  10. 1                    1007751                               |    |--Clustered Index Seek(OBJECT:([testcursor].[dbo].[S_AUDIT_ITEM].[S_AUDIT_ITEM_P1] AS   
  11. 16401                1                                     |--Table Scan(OBJECT:([testcursor].[dbo].[S_USER] AS [T2]))  

接下來,我們使用其他類型的游標進行測試,從它們的測試結(jié)果會發(fā)現(xiàn):

當使用STATIC、KEYSET、READ_ONLY、FAST_FORWARD類型的游標,可以得到理想的執(zhí)行計劃(索引S_AUDIT_ITEM_M3上使用索引查找)。

但是,如果使用其他第二類游標類型,得到的執(zhí)行計劃就不甚理想了(索引S_AUDIT_ITEM_M4上使用索引掃描)。

從上面的測試,我們知道STATIC、KEYSET、READ_ONLY及FAST_FORWARD游標可以帶給我們同樣的理想結(jié)果。那么,這些游標有什么共同點?

我們可以分析一下兩大游標類型執(zhí)行計劃的不同:

1. STATIC、KEYSET、READ_ONLY、FAST_FORWARD類型游標的執(zhí)行計劃:

  1. Executes             StmtText                                                                                                              
  2. -------------------- --------------------------------------------------------------------------------------------------------------------  
  3. 1                    OPEN curTest                                                                                                          
  4. 1                      |--Clustered Index Insert(OBJECT:(CWT), SET:([CWT].[COLUMN0] = [testcursor].[dbo].[S_AUDIT_ITEM].[CONFLICT_ID] as   
  5. 1                           |--Sequence Project(DEFINE:([Expr1008]=i4_row_number))                                                         
  6. 1                                |--Segment                                                                                                
  7. 1                                     |--Sort(ORDER BY:([T1].[OPERATION_DT] ASC))                                                          
  8. 1                                          |--Nested Loops(Left Outer Join, WHERE:([testcursor].[dbo].[S_AUDIT_ITEM].[USER_ID] as [T1].[U  
  9. 1                                               |--Nested Loops(Inner Join, OUTER REFERENCES:([Uniq1004], [T1].[ROW_ID]) OPTIMIZED)        
  10. 1                                               |    |--Index Seek(OBJECT:([testcursor].[dbo].[S_AUDIT_ITEM].[S_AUDIT_ITEM_M3] AS [T1]),   
  11. 4                                               |    |--Clustered Index Seek(OBJECT:([testcursor].[dbo].[S_AUDIT_ITEM].[S_AUDIT_ITEM_P1]   
  12. 4                                               |--Table Scan(OBJECT:([testcursor].[dbo].[S_USER] AS [T2]))                                
  13.                                                                                                       
  14. Executes             StmtText                                                                                        StmtId      NodeId    
  15. -------------------- ----------------------------------------------------------------------------------------------- ----------- --------  
  16. 1                    FETCH NEXT FROM curTest INTO @CONFLICT_ID                       2           1           
  17. 1                      |--Clustered Index Seek(OBJECT:(CWT), SEEK:([CWT].[ROWID]=FETCH_RANGE((0))) ORDERED FORWARD)  2           2         

2. dynamic類型游標的執(zhí)行計劃

  1. Executes   StmtText                                                                                                                      
  2. ---------------------------------------------------------------------------------------------------------------------------------------  
  3. 1          FETCH NEXT FROM curTest                                                                                                       
  4.                                                                                                                                          
  5. 1            |--Clustered Index Insert(OBJECT:(CWT), SET:([CWT].[COLUMN0] = [testcursor].[dbo].[S_AUDIT_ITEM].[ROW_ID] as [T1].[ROW_ID]  
  6. 1                 |--Compute Scalar(DEFINE:([Expr1008]=CWT_ROWID()))                                                                     
  7. 1                      |--Nested Loops(Left Outer Join, WHERE:([testcursor].[dbo].[S_AUDIT_ITEM].[USER_ID] as [T1].[USER_ID]=[testcurso  
  8. 1                           |--Nested Loops(Inner Join, OUTER REFERENCES:([Uniq1004], [T1].[ROW_ID]))                                    
  9. 1                           |    |--Index Scan(OBJECT:([testcursor].[dbo].[S_AUDIT_ITEM].[S_AUDIT_ITEM_M4] AS [T1]), ORDERED BACKWARD)   
  10. 1007751                     |    |--Clustered Index Seek(OBJECT:([testcursor].[dbo].[S_AUDIT_ITEM].[S_AUDIT_ITEM_P1] AS [T1]), SEEK:([T  
  11. 1                           |--Table Scan(OBJECT:([testcursor].[dbo].[S_USER] AS [T2]))  

比較一下兩個執(zhí)行計劃的FETCH NEXT部分(SQL Server在游標打開階段不會讀取表):在***個執(zhí)行計劃中,F(xiàn)ETCH是直接從臨時對象CWT中得到行,然后從CWT.ROWID中找到相應(yīng)范圍。而在第二個計劃中,F(xiàn)ETCH是動態(tài)的而且是真正對表進行了讀取,從表中取得數(shù)據(jù)。
 

責任編輯:艾婧 來源: ITPUB
相關(guān)推薦

2011-04-06 08:54:38

游標腳本性能問題

2011-04-07 11:02:52

游標

2010-11-16 15:40:21

oracle游標

2011-04-19 15:38:16

MongodbCursor

2010-11-16 15:11:52

Oracle隱式游標

2010-11-16 15:23:28

Oracle游標

2010-08-03 12:58:29

DB2游標循環(huán)

2010-05-26 18:08:30

Linux性能監(jiān)控

2010-07-26 11:27:43

SQL Server打

2013-05-20 16:09:39

SQL Server

2010-07-23 18:33:57

SQL Server游

2021-11-17 08:11:35

MySQL

2010-09-26 13:51:48

SQL游標

2010-04-02 09:51:37

SQL Server

2010-04-21 15:02:50

Oracle使用游標

2010-04-21 15:10:35

Oracle游標

2019-10-16 00:37:36

Oracle數(shù)據(jù)庫游標數(shù)

2010-11-04 10:32:18

DB2游標原理

2022-05-11 15:06:02

MySQL游標SQL

2010-10-22 13:34:49

SQL Server游
點贊
收藏

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