精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

索引掃描時,對同一個葉子塊訪問多次的原因初探

運維 數據庫運維
在觀察索引掃描會按何種次序進行索引塊的訪問時,我發現了一種現象,即會有部分葉子塊被訪問兩次或更多。以下是我自己對這種現象的重現,以及對產生該現象原因的初步判斷。但截至目前,我并未找到有官方文檔對相關內容的介紹。

[[397702]]

本文轉載自微信公眾號「數據和云」,作者趙勇。轉載本文請聯系數據和云公眾號。

在觀察索引掃描會按何種次序進行索引塊的訪問時,我發現了一種現象,即會有部分葉子塊被訪問兩次或更多。以下是我自己對這種現象的重現,以及對產生該現象原因的初步判斷。但截至目前,我并未找到有官方文檔對相關內容的介紹。因此,如果大家有不同的看法,或者可以提供相關的官方文檔介紹,也歡迎在文末留言區指正、討論和提供。

先創建以下測試環境,以重現相關現象。創建測試表,其中C1列為CHAR(256),目的是使該列占用字節數較多,使得后面在該列上創建索引時,可以用較少的行數構建出2層的索引。

  1. SQL> create table test0429 (id number,c1 char(256),v1 varchar2(256)); 
  2.  
  3. Table created. 

C1中插入的值為‘01’+254個空格,‘02’+254個空格…這樣的值。

  1. SQL> insert into test0429 select rownum id,lpad(rownum,2,'0') c1,rownum v1 from dual connect by rownum<=50; 
  2.  
  3. 50 rows created. 
  4.  
  5.  
  6. SQL> commit
  7.  
  8. Commit complete. 

在C1列上創建索引:

  1. SQL> create index ind_test0429_c1 on test0429(c1); 
  2.  
  3. Index created. 

查詢該索引的OBJECT_ID,以便查看其樹形結構。

  1. SQL> select object_id,object_name,object_type from user_objects where object_name='IND_TEST0429_C1'
  2.  
  3.  OBJECT_ID OBJECT_NAME                 OBJECT_TYPE 
  4. ---------- ----------------------------------- ------------------- 
  5.      97504 IND_TEST0429_C1             INDEX 
  6.  
  7.  
  8. SQL> alter session set events 'immediate trace name treedump level 97504'
  9.  
  10. Session altered. 
  11.  
  12. SQL> select * from v$diag_info; 
  13.  
  14.    INST_ID NAME 
  15. ---------- ---------------------------------------------------------------- 
  16. VALUE 
  17. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  18.      1 Diag Enabled 
  19. TRUE 
  20.  
  21.      1 ADR Base 
  22. /oradata/app/oracle 
  23.  
  24.      1 ADR Home 
  25. /oradata/app/oracle/diag/rdbms/orcl/orcl 
  26.  
  27.      1 Diag Trace 
  28. /oradata/app/oracle/diag/rdbms/orcl/orcl/trace 
  29.  
  30.      1 Diag Alert 
  31. /oradata/app/oracle/diag/rdbms/orcl/orcl/alert 
  32.  
  33.      1 Diag Incident 
  34. /oradata/app/oracle/diag/rdbms/orcl/orcl/incident 
  35.  
  36.      1 Diag Cdump 
  37. /oradata/app/oracle/diag/rdbms/orcl/orcl/cdump 
  38.  
  39.      1 Health Monitor 
  40. /oradata/app/oracle/diag/rdbms/orcl/orcl/hm 
  41.  
  42.      1 Default Trace File 
  43. /oradata/app/oracle/diag/rdbms/orcl/orcl/trace/orcl_ora_2751.trc 
  44.  
  45.      1 Active Problem Count 
  46.  
  47.      1 Active Incident Count 
  48. 17 
  49.  
  50.  
  51. 11 rows selected. 

在對應的跟蹤文件中,看到的索引結構為1個根節點,2個葉子節點。如下所示:

  1. ----- begin tree dump 
  2. branch: 0x180414b 25182539 (0: nrow: 2, level: 1) 
  3.    leaf: 0x180414c 25182540 (-1: nrow: 26 rrow: 26) 
  4.    leaf: 0x180414d 25182541 (0: nrow: 24 rrow: 24) 
  5. ----- end tree dump 

查詢根節點和最左側葉子節點的數據塊所在文件塊及塊號,準備DUMP其數據塊,以便查看其中的內容。

  1. SQL> select DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(to_number('&&p3_value','xxxxxxxx')) FILE#, 
  2.        DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(to_number('&&p3_value','xxxxxxxx')) BLOCK# 
  3. from dual;  2    3   
  4. Enter value for p3_value: 180414b 
  5. old   1: select DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(to_number('&&p3_value','xxxxxxxx')) FILE#, 
  6. new   1: select DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(to_number('180414b','xxxxxxxx')) FILE#, 
  7. old   2:    DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(to_number('&&p3_value','xxxxxxxx')) BLOCK# 
  8. new   2:    DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(to_number('180414b','xxxxxxxx')) BLOCK# 
  9.  
  10.      FILE#     BLOCK# 
  11. ---------- ---------- 
  12.      6  16715 
  13.  
  14. SQL> undefine p3_value 
  15. SQL> select DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(to_number('&&p3_value','xxxxxxxx')) FILE#, 
  16.        DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(to_number('&&p3_value','xxxxxxxx')) BLOCK# 
  17. from dual;   2    3   
  18. Enter value for p3_value: 180414c 
  19. old   1: select DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(to_number('&&p3_value','xxxxxxxx')) FILE#, 
  20. new   1: select DBMS_UTILITY.DATA_BLOCK_ADDRESS_FILE(to_number('180414c','xxxxxxxx')) FILE#, 
  21. old   2:    DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(to_number('&&p3_value','xxxxxxxx')) BLOCK# 
  22. new   2:    DBMS_UTILITY.DATA_BLOCK_ADDRESS_BLOCK(to_number('180414c','xxxxxxxx')) BLOCK# 
  23.  
  24.      FILE#     BLOCK# 
  25. ---------- ---------- 
  26.      6  16716 

DUMP根塊和最左側葉子塊中的內容到跟蹤文件中。

  1. SQL> alter system dump datafile 6 block min 16715 block max 16716; 
  2.  
  3. System altered. 

從跟蹤文件中,可以看到根塊中的主要內容如下所示(為節省篇幅,以下只列出與本主題相關的主要內容,以下其它類似內容亦做了相關處理,不再重復說明):

  1. kdxcolev 1 
  2. KDXCOLEV Flags = - - - 
  3. kdxcolok 0 
  4. kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y 
  5. kdxconco 2 
  6. kdxcosdc 0 
  7. kdxconro 1 
  8. kdxcofbo 30=0x1e 
  9. kdxcofeo 8048=0x1f70 
  10. kdxcoavs 8018 
  11. kdxbrlmc 25182540=0x180414c 
  12. kdxbrsno 0 
  13. kdxbrbksz 8056 
  14. kdxbr2urrc 3 
  15. row#0[8048] dba: 25182541=0x180414d 
  16. col 0; len 2; (2):  32 37 
  17. col 1; TERM 
  18. ----- end of branch block dump ----- 

從上面的倒數第三行的內容中可知,最右側的葉子塊中的最小索引鍵值為‘27’+254個空格。

從跟蹤文件中,可以看到最左側葉子塊中的主要內容如下所示:

  1. kdxcolev 0 
  2. KDXCOLEV Flags = - - - 
  3. kdxcolok 0 
  4. kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y 
  5. kdxconco 2 
  6. kdxcosdc 0 
  7. kdxconro 26 
  8. kdxcofbo 88=0x58 
  9. kdxcofeo 1090=0x442 
  10. kdxcoavs 1002 
  11. kdxlespl 0 
  12. kdxlende 0 
  13. kdxlenxt 25182541=0x180414d 
  14. kdxleprv 0=0x0 
  15. kdxledsz 0 
  16. kdxlebksz 8032 
  17. row#0[7765] flag: ------, lock: 0, len=267 
  18. col 0; len 256; (256): 
  19.  30 31 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 
  20.  ...... 
  21.  20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 
  22.  20 20 20 20 20 20 
  23. col 1; len 6; (6):  01 80 41 47 00 00 
  24. row#1[7498] flag: ------, lock: 0, len=267 
  25. col 0; len 256; (256): 
  26.  30 32 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 
  27.  ...... 
  28. row#25[1090] flag: ------, lock: 0, len=267 
  29. col 0; len 256; (256): 
  30.  32 36 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 
  31.  ...... 
  32.  20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 
  33.  20 20 20 20 20 20 
  34. col 1; len 6; (6):  01 80 41 47 00 19 
  35. ----- end of leaf block dump ----- 
  36. End dump data blocks tsn: 7 file#: 6 minblk 16715 maxblk 16716 

為跟蹤索引數據塊被訪問的情況,打開10200跟蹤事件。

  1. SQL> alter session set events '10200 trace name context forever,level 1'
  2.  
  3. Session altered. 

查詢位于最左側葉子塊中的數據,由于是等值查詢,且C1列上無重復值,故以下查詢會返回1行。

  1. SQL> set lines 200 pages 60 
  2.  
  3. SQL> select c1 from test0429 where c1='01';                                                                      
  4.  
  5. C1 
  6. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  7. 01 

由于我們在C1列上創建的索引不是唯一索引,所以此時,對索引的訪問方法為索引范圍掃描。如下圖所示:

  1. SQL> select * from table(dbms_xplan.display_cursor('','','typical')); 
  2.  
  3. PLAN_TABLE_OUTPUT 
  4. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  5. SQL_ID  3kt1uqh283qbx, child number 0 
  6. ------------------------------------- 
  7. select c1 from test0429 where c1='01' 
  8.  
  9. Plan hash value: 1267036809 
  10.  
  11. ------------------------------------------------------------------------------------ 
  12. | Id  | Operation        | Name            | Rows  | Bytes | Cost (%CPU)| Time     | 
  13. ------------------------------------------------------------------------------------ 
  14. |   0 | SELECT STATEMENT |                 |       |       |     1 (100)|          | 
  15. |*  1 |  INDEX RANGE SCAN| IND_TEST0429_C1 |     1 |   257 |     1   (0)| 00:00:01 | 
  16. ------------------------------------------------------------------------------------ 
  17.  
  18.  
  19. Predicate Information (identified by operation id): 
  20. --------------------------------------------------- 
  21.  
  22.    1 - access("C1"='01'
  23.  
  24.  
  25. 18 rows selected. 

查看10200跟蹤文件中的輸出,我們可以看到先訪問了索引根塊,然后訪問了最左側的葉子塊。這是符合預期的。但我們可以看到,最左側的葉子塊訪問了2次。

  1. ktrgtc2(): started for block <0x0007 : 0x0180414b> objd: 0x00017ce0 
  2. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017ce0 
  3. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017ce0 

之所以被訪問兩次,我認為其過程如下:

  1. 訪問索引根塊,即訪問“block <0x0007 : 0x0180414b>”;
  2. 由于條件值‘01’小于根塊中,指向第二個葉子塊的索引條目中的值‘27’,所以,需要訪問索引最左側的葉子塊,即訪問“<0x0007 : 0x0180414c>”;
  3. 在最左側的葉子塊中找到了第一行滿足條件的記錄ROW0。暫停繼續掃描,而將第一行返回;
  4. 繼續在最左側的葉子塊中查找是否有滿足條件的記錄。所以,會再次訪問最左側的葉子塊;
  5. 在訪問ROW1時,得到了值‘02’+254個空格,該值大于‘01’,故整個索引中已不會再有滿足條件的記錄,所以,結束掃描,退出;
  6. 如果在葉子塊的掃描中,還能繼續找到滿足條件值的記錄,就不是每找到一行,就暫停掃描并返回當前結果了,而是根據ARRAYSIZE中的值,每湊夠該參數指定的行數,才會暫停掃描并返回結果,然后再繼續掃描。當發生“再繼續掃描”這個動作時,相應的葉子塊會被再一次訪問。

針對6中所述,我們進行如下測試。將ARRAYSIZE設置為3,即每湊夠3行即暫停掃描,返回結果。而該參數的默認值為15。

  1. SQL> show arraysize 
  2. arraysize 15 
  3. SQL> set arraysize 3 
  4. SQL> show arraysize 
  5. arraysize 3 

執行以下查詢,應該返回2行。

  1. SQL> select c1 from test0429 where c1<='02'
  2.  
  3. C1 
  4. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  5. 01 
  6.  
  7.  
  8. 02 

其對數據塊的訪問情況如下:

  1. ktrgtc2(): started for block <0x0007 : 0x0180414b> objd: 0x00017ce0 
  2. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017ce0 
  3. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017ce0 

執行以下查詢,會返回3行。

  1. SQL> select c1 from test0429 where c1<='03'
  2.  
  3. C1 
  4. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  5. 01 
  6.  
  7.  
  8. 02 
  9.  
  10.  
  11. 03 

其對數據塊的訪問情況如下:

  1. ktrgtc2(): started for block <0x0007 : 0x0180414b> objd: 0x00017ce0 
  2. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017ce0 
  3. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017ce0 

執行以下查詢,會返回4行。

  1. SQL> select c1 from test0429 where c1<='04'
  2.  
  3. C1 
  4. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  5. 01 
  6.  
  7.  
  8. 02 
  9.  
  10.  
  11. 03 
  12.  
  13.  
  14. 04 

其對數據塊的訪問情況如下:

  1. ktrgtc2(): started for block <0x0007 : 0x0180414b> objd: 0x00017ce0 
  2. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017ce0 
  3. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017ce0 
  4. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017ce0 

這里之所以會出現對最左側葉子塊的第三次訪問。是因為當其返回第一行后,第二次訪問葉子塊期間,找到了3行滿足條件的記錄。由于已達到了ARRAYSIZE的限制,所以,要暫停掃描,返回結果。然后再繼續掃描葉子塊中的剩余值,看看是否仍有滿足條件的記錄。因此,會出現對最左側葉子塊的第三次訪問。

如果我們發出一條查詢最左側葉子塊中的最大值的SQL,又會是什么訪問情況呢?

  1. SQL> select c1 from test0429 where c1='26'
  2.  
  3. C1 
  4. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  5. 26 

我們可以看到是訪問了全部三個索引塊,并且各訪問了一次,沒有重復訪問情況的發生。

  1. ktrgtc2(): started for block <0x0007 : 0x0180414b> objd: 0x00017ce0 
  2. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017ce0 
  3. ktrget2(): started for block  <0x0007 : 0x0180414d> objd: 0x00017ce0 

之所以發生這種情況,我認為其原因是當其從根塊中的指針,訪問了最左側的葉子塊,找到一行滿足該條件的記錄。這時,會如前所述,暫停繼續掃描,返回結果。然后繼續掃描,但由于在第一次的掃描中,已了解到了該索引條目是本索引塊中的最后一個索引條目,所以,就直接沿著最左側葉子塊上指向其后一個葉子塊的指針,訪問了位于其右側的葉子塊,即訪問了“block <0x0007 : 0x0180414d> ”。顯然,由于該塊中的ROW0已經是‘27’+254個空格了,已經大于了條件值‘26’,因此,結束查詢。

如果我們查詢的結果是存在于相鄰的兩個葉子塊中時,其訪問情況如下:在下面的查詢中,有兩行記錄位于最左側的葉子塊中,而一行記錄位于其右側的葉子塊中。

  1. SQL> select c1 from test0429 where c1>='25' and c1<='27'
  2.  
  3. C1 
  4. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  5. 25 
  6.  
  7.  
  8. 26 
  9.  
  10.  
  11. 27 

其中索引塊的訪問情況如下:

  1. ktrgtc2(): started for block <0x0007 : 0x0180414b> objd: 0x00017ce0 
  2. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017ce0 
  3. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017ce0 
  4. ktrget2(): started for block  <0x0007 : 0x0180414d> objd: 0x00017ce0 

而當我們查詢的結果是存在于相鄰的兩個葉子塊中,并且會湊夠ARRAYSIZE參數所指定的3行時,其訪問情況會有變化。

  1. SQL> select c1 from test0429 where c1>='25' and c1<='28'
  2.  
  3. C1 
  4. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  5. 25 
  6.  
  7.  
  8. 26 
  9.  
  10.  
  11. 27 
  12.  
  13.  
  14. 28 

這時,我們觀察到的訪問情況如下:

  1. ktrgtc2(): started for block <0x0007 : 0x0180414b> objd: 0x00017ce0 
  2. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017ce0 
  3. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017ce0 
  4. ktrget2(): started for block  <0x0007 : 0x0180414d> objd: 0x00017ce0 
  5. ktrget2(): started for block  <0x0007 : 0x0180414d> objd: 0x00017ce0 

如上所示,這里之所以會對位于右側的葉子塊訪問2次,其原因是當其訪問右側的葉子塊,并獲取到滿足條件的‘27’和‘28’兩條記錄時,此時,已經湊夠3條了(另1條是‘26’),所以,要暫停掃描,返回結果,然后繼續掃描。因此,這時會再次訪問右側的葉子塊。

如果換成唯一索引,其訪問行為,又會有一些差異。刪除原索引,仍在C1列上創建唯一索引。

  1. SQL> drop index ind_test0429_c1; 
  2.  
  3. Index dropped. 
  4.  
  5. SQL> create unique index ind_unique_test0429_c1 on test0429(c1); 
  6.  
  7. Index created. 

查看新的唯一索引OBJECT_ID,以便查看其索引樹形結構。

  1. SQL> select object_id,object_name,object_type from user_objects where object_name='IND_UNIQUE_TEST0429_C1'
  2.  
  3.  OBJECT_ID OBJECT_NAME                 OBJECT_TYPE 
  4. ---------- ----------------------------------- ------------------- 
  5.      97521 IND_UNIQUE_TEST0429_C1          INDEX 
  6.  
  7. SQL> alter session set events 'immediate trace name treedump level 97521'
  8.  
  9. Session altered. 

如下所示,我們可以看到該結構與此前的樹形結構是相同的。

  1. branch: 0x180414b 25182539 (0: nrow: 2, level: 1) 
  2.    leaf: 0x180414c 25182540 (-1: nrow: 26 rrow: 26) 
  3.    leaf: 0x180414d 25182541 (0: nrow: 24 rrow: 24) 
  4. ----- end tree dump 

再次DUMP出根塊和最左側葉子塊中的內容,如下所示:

  1. kdxcolev 1 
  2. KDXCOLEV Flags = - - - 
  3. kdxcolok 0 
  4. kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y 
  5. kdxconco 1 
  6. kdxcosdc 0 
  7. kdxconro 1 
  8. kdxcofbo 30=0x1e 
  9. kdxcofeo 8049=0x1f71 
  10. kdxcoavs 8019 
  11. kdxbrlmc 25182540=0x180414c 
  12. kdxbrsno 0 
  13. kdxbrbksz 8056 
  14. kdxbr2urrc 3 
  15. row#0[8049] dba: 25182541=0x180414d 
  16. col 0; len 2; (2):  32 37 

我們可以看到根塊中,顯示位于第二個葉子塊中的最小值的起始兩位是‘27’,而最左側葉子塊中的內容如下,可以看到該塊中的最大值,仍然是‘26’+254個空格。

  1. kdxcolev 0 
  2. KDXCOLEV Flags = - - - 
  3. kdxcolok 0 
  4. kdxcoopc 0x80: opcode=0: iot flags=--- is converted=Y 
  5. kdxconco 1 
  6. kdxcosdc 0 
  7. kdxconro 26 
  8. kdxcofbo 88=0x58 
  9. kdxcofeo 1116=0x45c 
  10. kdxcoavs 1028 
  11. kdxlespl 0 
  12. kdxlende 0 
  13. kdxlenxt 25182541=0x180414d 
  14. kdxleprv 0=0x0 
  15. kdxledsz 6 
  16. kdxlebksz 8032 
  17. row#0[7766] flag: ------, lock: 0, len=266, data:(6):  01 80 41 47 00 00 
  18. col 0; len 256; (256): 
  19.  30 31 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 
  20.  ...... 
  21.  20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 
  22.  20 20 20 20 20 20 
  23. row#1[7500] flag: ------, lock: 0, len=266, data:(6):  01 80 41 47 00 01 
  24. col 0; len 256; (256): 
  25.  30 32 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 
  26.  ...... 
  27. row#25[1116] flag: ------, lock: 0, len=266, data:(6):  01 80 41 47 00 19 
  28. col 0; len 256; (256): 
  29.  32 36 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 
  30.  ...... 
  31.  20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 
  32.  20 20 20 20 20 20 
  33. ----- end of leaf block dump ----- 
  34. End dump data blocks tsn: 7 file#: 6 minblk 16715 maxblk 16716 

再次執行只返回1行的查詢。

  1. SQL> select c1 from test0429 where c1='01'
  2.  
  3. C1 
  4. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  5. 01 

但對索引的訪問方法,已經變為了索引唯一掃描,如下面的執行計劃所示:

  1. SQL> select * from table(dbms_xplan.display_cursor('','','typical')); 
  2.  
  3. PLAN_TABLE_OUTPUT 
  4. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  5. SQL_ID  3kt1uqh283qbx, child number 0 
  6. ------------------------------------- 
  7. select c1 from test0429 where c1='01' 
  8.  
  9. Plan hash value: 3124258820 
  10.  
  11. -------------------------------------------------------------------------------------------- 
  12. | Id  | Operation         | Name                   | Rows  | Bytes | Cost (%CPU)| Time     | 
  13. -------------------------------------------------------------------------------------------- 
  14. |   0 | SELECT STATEMENT  |                        |       |       |     1 (100)|          | 
  15. |*  1 |  INDEX UNIQUE SCAN| IND_UNIQUE_TEST0429_C1 |     1 |   257 |     1   (0)| 00:00:01 | 
  16. -------------------------------------------------------------------------------------------- 
  17.  
  18. Predicate Information (identified by operation id): 
  19. --------------------------------------------------- 
  20.  
  21.    1 - access("C1"='01'
  22.  
  23.  
  24. 18 rows selected. 

這時觀察到的對索引塊的訪問情況如下:

  1. ktrgtc2(): started for block <0x0007 : 0x0180414b> objd: 0x00017cf1  
  2. ktrgtc2(): started for block <0x0007 : 0x0180414c> objd: 0x00017cf1 

如上圖所示,我們可以看到,并沒有發生對最左側葉子塊的兩次訪問。這是由于唯一索引的特性導致的。由于唯一索引中不會有重復值,所以,當找到一行記錄,就不必再判斷是否還有其它滿足條件的記錄了。因為在唯一索引中,要么沒有對應條件值,要么就只會有一條。因此,找到一行后,就可以結束了。

如果我們對最左側葉子塊中的最大值做查詢,其結果如下:

  1. SQL> select c1 from test0429 where c1='26'
  2.  
  3. C1 
  4. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  5. 26 

如下所示,我們可以看到,仍然是訪問2個索引塊。并且,不會去訪問第二個葉子塊。

  1. ktrgtc2(): started for block <0x0007 : 0x0180414b> objd: 0x00017cf1 
  2. ktrgtc2(): started for block <0x0007 : 0x0180414c> objd: 0x00017cf1 

但是,當執行以下查詢時,情況會發生變化。

  1. SQL> select c1 from test0429 where c1<='04'
  2.  
  3. C1 
  4. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  5. 01 
  6.  
  7.  
  8. 02 
  9.  
  10.  
  11. 03 
  12.  
  13.  
  14. 04 

由于WHERE子句中不是等值比較,所以,盡管是在唯一索引上的掃描,但訪問方法又回到了索引范圍掃描的方法。如下所示:

  1. SQL> select * from table(dbms_xplan.display_cursor('','','typical')); 
  2.  
  3. PLAN_TABLE_OUTPUT 
  4. -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
  5. SQL_ID  9g9p54332fyd4, child number 0 
  6. ------------------------------------- 
  7. select c1 from test0429 where c1<='04' 
  8.  
  9. Plan hash value: 3622766470 
  10.  
  11. ------------------------------------------------------------------------------------------- 
  12. | Id  | Operation        | Name                   | Rows  | Bytes | Cost (%CPU)| Time     | 
  13. ------------------------------------------------------------------------------------------- 
  14. |   0 | SELECT STATEMENT |                        |       |       |     2 (100)|          | 
  15. |*  1 |  INDEX RANGE SCAN| IND_UNIQUE_TEST0429_C1 |     4 |  1028 |     2   (0)| 00:00:01 | 
  16. ------------------------------------------------------------------------------------------- 
  17.  
  18. Predicate Information (identified by operation id): 
  19. --------------------------------------------------- 
  20.  
  21.    1 - access("C1"<='04'
  22.  
  23.  
  24. 18 rows selected. 

而且,其訪問索引塊的情況,也與此前在非唯一索引上訪問,并返回4行結果時的情形相同了。如下所示:

  1. ktrgtc2(): started for block <0x0007 : 0x0180414b> objd: 0x00017cf1 
  2. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017cf1 
  3. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017cf1 
  4. ktrget2(): started for block  <0x0007 : 0x0180414c> objd: 0x00017cf1 

關于作者

趙勇,云和恩墨北區SQL審核和優化團隊總監,從業超過20年,專職于SQL優化與SQL質量管控的服務工作,作為項目負責人和主要實施人員,深度融入金融、保險、政府,運營商等多個行業,結合行業系統特性,為客戶優化了大量問題SQL,同時也為運營商、銀行等客戶的核心系統提供SQL質量審核服務,助其防患于未然,為系統高質量運行提供保障。

 

責任編輯:武曉燕 來源: 數據和云
相關推薦

2016-12-15 08:54:52

線程sessionopenSession

2015-10-16 13:41:52

程序對象設計

2016-12-20 13:55:52

2009-06-09 12:38:12

NetBeanseclipse

2019-08-20 10:24:39

HTTPSSSHLinux

2009-11-20 17:10:43

Oracle B樹索引

2022-08-11 16:01:26

勒索軟件網絡攻擊

2021-08-16 20:48:34

嵌入式單片機信息

2024-09-05 16:01:55

2022-07-26 00:00:02

TCPUDPMAC

2024-04-28 18:31:03

2017-08-17 10:53:10

Google代碼倉庫

2024-03-18 08:21:06

TCPUDP協議

2015-11-12 15:14:48

ZD至頂網CIO與應用

2021-04-08 14:51:20

Python編碼語言

2023-09-13 13:05:01

Java項目

2024-03-05 10:07:22

TCPUDP協議

2019-01-28 09:43:21

IP地址子網掩碼

2019-07-09 14:42:17

SQLexplain索引

2024-11-29 09:41:17

點贊
收藏

51CTO技術棧公眾號

mm视频在线视频| 国产精品高潮呻吟久久久| 久久激情av| 色综合久久中文字幕| 亚洲国产欧洲综合997久久| 国产精品视频一二区| 影院欧美亚洲| 在线观看国产精品淫| 九色91porny| 成年美女黄网站色大片不卡| 亚洲视频一区在线观看| 精品无人区一区二区三区| 尤物视频免费观看| 国产精品s色| 亚洲最大在线视频| 日批免费观看视频| 久久er热在这里只有精品66| 五月天视频一区| 自拍偷拍一区二区三区| 亚洲av成人精品毛片| 欧洲一级精品| 亚洲精品国产一区二区精华液| 精品一区二区久久久久久久网站| 中文字幕在线播出| 99亚洲一区二区| 久久国内精品一国内精品| 免费的av网站| 视频一区中文字幕精品| 精品视频在线免费| 草草久久久无码国产专区| 污污在线观看| 亚洲欧美综合在线精品| 日本精品国语自产拍在线观看| 性中国xxx极品hd| 九一九一国产精品| 国产精品美女www| 欧美精品韩国精品| 国产欧美三级| 欧美劲爆第一页| 91成人福利视频| 久久精品亚洲人成影院| 中文字幕日韩欧美| 色欲AV无码精品一区二区久久| 老汉色老汉首页av亚洲| 日韩亚洲欧美在线观看| 天堂在线一区二区三区| 高清在线一区| 在线欧美一区二区| 50路60路老熟妇啪啪| 欧美xxxhd| 午夜婷婷国产麻豆精品| 99在线免费视频观看| 青春草免费在线视频| 一区二区三区在线视频免费观看| 中国成人亚色综合网站| 日本在线观看www| 国产精品人妖ts系列视频| 奇米精品在线| 国产精品ⅴa有声小说| 久久久www成人免费无遮挡大片| 精品一区二区三区日本| 亚洲日本在线播放| 国产性做久久久久久| 欧美少妇一区| 成人av毛片| 中文字幕在线视频一区| 视频一区二区视频| av网站网址在线观看| 亚洲自拍偷拍九九九| 黄色三级中文字幕| 天堂在线观看免费视频| 成人性色生活片免费看爆迷你毛片| 91久久在线观看| 国产极品999| www.久久久久久久久| 麻豆亚洲一区| 日韩黄色影院| 亚洲精品久久嫩草网站秘色| 日韩小视频网站| 三级在线观看视频| 欧美性色aⅴ视频一区日韩精品| 欧美婷婷精品激情| 日韩成人视屏| 亚洲高清一区二| 亚洲国产天堂av| 欧美hd在线| 国外色69视频在线观看| 国产伦精品一区二区三区视频我| 蜜桃av一区二区三区电影| 亚洲在线视频福利| 天堂在线中文资源| 国产精品久久久久久久久久久免费看| 国产香蕉一区二区三区| 国产777精品精品热热热一区二区| 一本色道久久综合亚洲91 | 精品人伦一区二区三区| 可以直接在线观看的av| 亚洲人精品午夜| 无码av天堂一区二区三区| 亚洲成av在线| 欧美成人性战久久| 国产123在线| 国产精品激情| 国产精品精品一区二区三区午夜版 | 超碰男人的天堂| 日韩欧美精品综合| 久久人人爽人人| 中文字幕精品无码亚| 成人午夜电影久久影院| 视频一区视频二区视频| 国产第一页在线| 欧美日韩精品一区二区| 超碰97在线资源站| 亚洲精品成人影院| 日本精品视频在线观看| 性做久久久久久久久久| 综合欧美亚洲日本| 日韩中文字幕二区| 国产乱人伦丫前精品视频| 亚洲色图国产精品| 日韩欧美亚洲一区二区三区| 久久99精品国产91久久来源| 免费日韩av电影| 成年人视频免费在线播放| 欧美喷水一区二区| 国产aⅴ激情无码久久久无码| 国产在线不卡| 亚洲一区二区在线| 8888四色奇米在线观看| 精品美女久久久久久免费| 麻豆免费在线观看视频| 99久精品视频在线观看视频| 日韩av不卡在线| 桃花色综合影院| 午夜精品aaa| 久久久久无码国产精品一区李宗瑞| 久久中文字幕av一区二区不卡| 日本国产一区二区三区| 五月激情婷婷网| 午夜久久久影院| 美女露出粉嫩尿囗让男人桶| 欧美激情亚洲| 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 免费人成年激情视频在线观看| 免费人成精品欧美精品| 欧美一区二区三区四区五区六区| 人成在线免费网站| 亚洲精品一区二三区不卡| 国产免费av一区二区| 成人免费毛片aaaaa**| 毛片av在线播放| 嫩呦国产一区二区三区av| 欧美成人性生活| 精品人妻一区二区三区日产乱码| 亚洲欧美视频在线观看视频| 天天爽夜夜爽视频| 亚洲午夜精品一区二区国产| 99re在线国产| av中文字幕电影在线看| 亚洲黄色在线看| 久久久久久久久久免费视频| 91社区在线播放| 黄色片视频在线播放| 激情五月色综合国产精品| 国产精品久久久久久久美男| 岛国最新视频免费在线观看| 欧美日韩一区三区四区| 少妇被躁爽到高潮无码文| 国产999精品久久| 成人毛片一区二区| 精品日韩在线| 精品国产一区二区三区久久久| 一区二区视频网| 中文字幕中文字幕一区二区| av在线天堂网| 一区二区福利| 亚洲欧洲精品在线观看| gogo大尺度成人免费视频| 久久久久久91香蕉国产| 欧美日本网站| 制服丝袜av成人在线看| 九九九国产视频| 国产日韩欧美制服另类| 国产精品久久久久久久99| 亚洲国产网站| 日韩福利视频| 亚洲3区在线| 日韩女在线观看| 国产在线观看av| 亚洲精品成人免费| 一级特黄录像免费看| 亚洲成人自拍网| 亚洲精品色午夜无码专区日韩| 黑人巨大精品欧美一区| 久久99中文字幕| 久久香蕉国产| 精品国产乱码久久久久久蜜柚| 日本一区二区三区视频在线| 色综合久久88| 国产精品视频一区二区久久| 日韩精品中午字幕| 毛片在线免费播放| 午夜亚洲福利老司机| 天天操夜夜操av| 26uuu色噜噜精品一区二区| 久久6免费视频| 久热国产精品| 分分操这里只有精品| 日韩免费久久| 欧洲av一区| 日韩a级大片| 91传媒在线免费观看| 亚洲第一会所| 2018中文字幕一区二区三区| 超碰caoporn久久| 国产一区二区三区精品久久久| 性一交一乱一乱一视频| 欧美日韩成人激情| 五月婷婷激情视频| 亚洲高清久久久| 男人操女人的视频网站| 中文字幕一区在线观看| 国产一区二区三区四区五区六区| 成人免费毛片片v| 在线观看免费看片| 国产在线播放一区三区四| 国产免费999| 老司机午夜免费精品视频| 日韩精品 欧美| 伊人久久大香线蕉综合热线| 成人午夜免费剧场| 欧美激情黄色片| 视频一区亚洲| 精品国产乱码久久久久久果冻传媒| 国产一区二区三区四区hd| 中文无码日韩欧| 国产福利久久精品| 亚洲国产视频二区| 99久久99久久| 日韩中文字幕视频网| 成人av蜜桃| 成人直播在线观看| 国产精品一区在线观看| 草草视频在线一区二区| 国产精品对白刺激久久久| 91蝌蚪精品视频| 成人毛片网站| 国产精品极品在线观看| 精品国产一区二区三区免费| 盗摄牛牛av影视一区二区| 国产伦精品一区二区三区高清| 亚洲高清999| 国产91精品入口17c| a级日韩大片| 国产区欧美区日韩区| 亚洲国产精品嫩草影院久久av| 鲁片一区二区三区| 国产毛片一区二区三区| 亚洲欧美国产不卡| 亚洲草久电影| 久青草视频在线播放| 国产日韩欧美三级| 国产精品少妇在线视频| 美女www一区二区| 男插女视频网站| 波多野结衣视频一区| 中文字字幕码一二三区| 欧美韩国一区二区| 精品国产精品国产精品| 亚洲国产精品一区二区www在线 | 欧美色国产精品| 国产精品一区二区av白丝下载| 日韩欧美亚洲一区二区| 欧美一级特黄aaaaaa大片在线观看| 亚洲国产精品一区二区三区| 日韩av资源站| 久久激情视频久久| 91九色国产在线播放| 欧美中文字幕在线| 色综合久久久| 国产精品初高中精品久久| 精品日产免费二区日产免费二区| 天天爱天天做天天操| 亚洲每日在线| 亚洲欧美偷拍另类| 岛国av在线一区| 亚洲精品91在线| 亚洲综合免费观看高清完整版 | 成人亚洲欧美| 成人黄色大片在线免费观看| 97久久亚洲| 亚洲精品乱码久久久久久蜜桃91| 欧美日韩网址| 国产性生交xxxxx免费| 国产经典欧美精品| 亚洲无人区码一码二码三码的含义| 一区二区理论电影在线观看| 一级一片免费看| 日韩欧美国产1| eeuss影院www在线观看| 韩国19禁主播vip福利视频| 欧美日韩国产网站| 国产一级特黄a大片99| 久久国产亚洲精品| 妺妺窝人体色www在线小说| 精品一区中文字幕| 久久精品国产亚洲av久| 一区二区三区av电影| 一级片aaaa| 亚洲欧洲日产国码av系列天堂| 97超碰在线公开在线看免费| 国产极品精品在线观看| 青青视频一区二区| av影院在线播放| 久久99精品一区二区三区| 日韩av一二区| 亚洲一二三四久久| 国产免费无遮挡| 中文字幕亚洲一区二区三区五十路| 老牛影视精品| 国产亚洲欧美一区二区 | 99热成人精品热久久66| 懂色av一区二区三区蜜臀| 三上悠亚作品在线观看| 欧美视频三区在线播放| 日本福利片高清在线观看| 国内成人精品一区| 精品中文字幕一区二区三区| 亚洲一区二区在线看| 免费人成网站在线观看欧美高清| 实拍女处破www免费看| 福利一区视频在线观看| 天堂在线视频免费观看| 久久久久久久久久久网站| 午夜视频一区二区在线观看| 最近免费观看高清韩国日本大全| 久久91精品久久久久久秒播| 亚洲图片第一页| 欧美视频一区二区在线观看| 国产视频福利在线| 国产精品99久久久久久久久| 一道在线中文一区二区三区| 日本wwww视频| 久久久久国产精品厨房| 五月天综合激情| 亚洲精选在线观看| 69久成人做爰电影| 日本三级中国三级99人妇网站| 香蕉久久a毛片| 波多野吉衣中文字幕| 色偷偷久久一区二区三区| 国产成人天天5g影院在线观看| 国产91在线视频| 凹凸成人精品亚洲精品密奴| 亚洲污视频在线观看| 中文字幕日韩一区二区| 国产日韩免费视频| 欧美激情视频在线观看| 精品国产18久久久久久洗澡| 久激情内射婷内射蜜桃| 91伊人久久大香线蕉| 日本视频www色| 久久国产一区二区三区| 澳门精品久久国产| 欧美日韩第二页| 欧美韩国一区二区| 精品久久久久久亚洲综合网站| 国产做受69高潮| 欧美人与牛zoz0性行为| 国产aⅴ爽av久久久久| 亚洲午夜一区二区三区| 三区在线观看| 国产精品一区二区三区成人| 国产精品a级| 波多野结衣 在线| 欧美三区免费完整视频在线观看| 成人欧美在线| 国内外成人免费视频| 免费欧美日韩国产三级电影| xxxx日本少妇| 日韩国产高清视频在线| 国产精品一区二区免费福利视频| 国产高潮呻吟久久久| 26uuu亚洲婷婷狠狠天堂| 91成人国产综合久久精品| 欧美精品久久久久久久| 成人久久久久| 看全色黄大色黄女片18| 欧美网站大全在线观看| 狂野欧美激情性xxxx欧美| 日韩精品一区二区三区四区五区 | 欧美三级日韩在线| 日本色护士高潮视频在线观看| 欧美精品一区二区三区四区五区 | 久久久久久久久久久国产精品| 欧美日韩你懂得| а√天堂中文在线资源8| 在线观看一区二区三区三州| 白白色亚洲国产精品| 国产乱码一区二区|