1. 程式人生 > >oracle分割槽表中本地索引和全域性索引的適用場景

oracle分割槽表中本地索引和全域性索引的適用場景

【背景】分割槽表建立好了之後,如果需要最大化分割槽表的效能就需要結合索引的使用,分割槽表有兩種索引:本地索引和全域性索引。既然存在著兩種的索引型別,相信存在即合理。既然存在就會有存在的原因,也就是在特定的場景中就更能發揮出索引的效能的;

本文件通過測試,總結出兩種索引的適合的場景;

【測試環境】

資料庫版本:11.2.0.3

分割槽表的建立指令碼:

  1. CREATE TABLE SCOTT.PTB

  2. (

  3. GG1DM VARCHAR2(9 BYTE),

  4. SL NUMBER(18,4) ,

  5. DJBH VARCHAR2(20 BYTE)

  6. )

  7. NOCOMPRESS

  8. PARTITION BY LIST (GG1DM)

  9. (

  10. PARTITION PTABLE_P1 VALUES ('07'),

  11. PARTITION PTABLE_P2 VALUES ('08'),

  12. PARTITION PTABLE_P3 VALUES ('09')

  13. )

    然後插入大量的資料,再進行統計資訊的更新;

  14. select t3.table_name,t3.partition_name,t3.high_value,t3.num_rows,t3.blocks,t3.empty_blocks,t3.last_analyzed
  15. from dba_tab_partitions t3 where t3.table_name='PTABLE' order by t3.num_rows desc;
  16. 【開始測試】

    測試一、跨分割槽的資料查詢

    1.1 建立本地索引(注意:該列不是分割槽的列)

  17. SQL> CREATE INDEX SCOTT.IN_PTB ON SCOTT.PTB

  18. (DJBH)

  19. LOGGING

  20. LOCAL (

  21. PARTITION PTABLE_P1

  22. LOGGING

  23. NOCOMPRESS ,

  24. PARTITION PTABLE_P2

  25. LOGGING

  26. NOCOMPRESS ,

  27. PARTITION PTABLE_P3

  28. LOGGING

  29. NOCOMPRESS

  30. )

  31. SQL> select Segment_NAME,PARTITION_NAME,SEGMENT_TYPE from dba_segments a wherea.segment_name='IN_PTB';

  32. SEGMENT_NAME PARTITION_NAME         SEGMENT_TYPE

  33. ---------------- --------------------- ------------------

  34. IN_PTB PTABLE_P1         INDEX PARTITION

  35. IN_PTB PTABLE_P2         INDEX PARTITION

  36. IN_PTB PTABLE_P3     INDEX PARTITION

  37. LOCAL索引會在每個分割槽上面單獨建立INDEX PARTITION,類似於三個子索引;

    進行執行計劃的檢視

  38. SQL> select count(1) from scott.ptb where djbh='R23NAA002138250';

  39. COUNT(1)

  40. ----------

  41. 512

    1.2 建立全域性索引,原先的索引先drop(注意:該列不是分割槽的列)

  42. SQL> CREATE INDEX SCOTT.IN_PTB_L ON SCOTT.PTB

  43. (DJBH)

  44. NOLOGGING

  45. STORAGE (

  46. BUFFER_POOL DEFAULT

  47. FLASH_CACHE DEFAULT

  48. CELL_FLASH_CACHE DEFAULT

  49. )

  50. NOPARALLEL;

  51. SQL> select Segment_NAME,PARTITION_NAME,SEGMENT_TYPE from dba_segments a wherea.segment_name='IN_PTB_L';

  52. SEGMENT_NAME PARTITION_NAME         SEGMENT_TYPE

  53. -------------- --------------------- --------------------

  54. IN_PTB_L             INDEX

    進行執行計劃的檢視

    需要先重新整理buffer:

  55. alter system flush buffer_cache;

  56. select count(1) from scott.ptb where djbh='R23NAA002138250';

     

     測試一總結:以上那種情況因為djbh這一列是需要跨分割槽的,當查詢的條件是需要跨分割槽查詢內容的時候,LOCAL INDEX的效率比GLOBAL INDEX的效率要低,通過consistent gets和db block gets的對比可以看出來;

    測試二、分割槽內部的查詢

    2.1 分割槽內使用本地索引

  57. alter system flush buffer_cache;

  58. select count(1) from scott.ptb where djbh='R23NAA002138250' and GG1DM='07'; #該條件可以確定在單個分割槽裡面

    2.2 分割槽內使用全域性索引

  59. alter system flush buffer_cache;

  60. select  /*+ index(PTB IN_PTB_L) */  count(1) from scott.ptb where djbh='R23NAA002138250' and GG1DM='07';

    測試二總結:通過這組實驗可以看出來如果查詢的條件是在單個分割槽裡面查詢的時候,那麼LOCAL INDEX的效率比GLOBAL INDEX的效率要高。

    【總結】經過以上的測試可以發現全域性索引和本地索引的使用效率跟查詢條件有直接的影響,建立索引的時候需要根據業務的使用場景進行建立;

    而分割槽表的建立也是受使用場景所影響的,所以在建立分割槽表和分割槽索引的時候都需要事先了解業務的需求,儘量把業務需要統計的資訊放在一個同一個分割槽。這樣使分割槽表的效能實現最大化;