何建銳

          Java人生

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            2 隨筆 :: 0 文章 :: 0 評論 :: 0 Trackbacks
           

          在前段時間,由于項目的需要,在進行大量數據的批處理時,須考慮如何提高效率,在經過不斷的測試與研究后,發現在查詢數據庫時浪費了太多時間,之前針對各種需要已經創建了幾個索引,但所起效果不大,故便對索引進行研究及探索,如何合理的創建索引將是本文探索的主要問題。
          測試環境:
          操作系統:AIX      數據庫:IBM DB2

          為了便于測試,先創建一個表,并創建相關的索引以及插入一些數據。

           

          表結構如下所示:

          describe table sygjj_test_index

          Column                         Type      Type

          name                           schema    name               Length   Scale Nulls

          ID                             SYSIBM    VARCHAR           4       0  No   

          USERNAME                   SYSIBM    VARCHAR          20      0   Yes  

          SEX                           SYSIBM    VARCHAR           50      0   Yes  

          AGE                           SYSIBM    VARCHAR           4       0   Yes  

          CLASS                         SYSIBM    VARCHAR           50      0   Yes

          表索引結構如下:

          describe indexes for table sygjj_test_index show detail

          Index              Index              Unique         Number of          Column

          schema             name              rule           columns             names

          AFA           SY_TEST_KEY        P                          1+ID                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             

          AFA            SY_TEST_IDX1        D                2 +USERNAME+CLASS                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 

          AFA            SY_TEST_IDX2        D                           1 +AGE 
           

          select * from sygjj_test_index

          ID         USERNAME         SEX           AGE         CLASS                                            

          1             aa                m              20           computer                                          

          2             aa                m              20           computer

          3             bb                m              20           computer

          4             aca                f              23           computer

          5             asa                m              26           english

          6             aaa                m              20           computer

          7             dd                m              22           computer

           

          探索查詢時何時會利用username+class這個索引

          1.       當查詢條件中包含這兩個字段時,且select 后面緊跟的字段也只有usernameclass或它們之中的一個,這時索引都會起作用。

          例如:select username,class from sygjj_test_index where username='aa' and class='computer'

          2.       當查詢條件中包含這兩個字段,但select后面緊跟的字段不只是usernameclass時,這時索引不起作用。

          select * from sygjj_test_index where username='aa' and class='computer'

          3.       當查詢條件中只包含username時,且select 后面緊跟的字段也只有usernameclass或它們之中的一個,這時索引都會起作用。

          select class from sygjj_test_index where username='aa'

          4.       當查詢條件中只包含username時,但select后面緊跟的字段不只是usernameclass時,這時索引不起作用。

          select username,class,age from sygjj_test_index where username='aa'

          5.       當查詢條伯中只包含class時,這時索引是不起作用的

          select username,class from sygjj_test_index where class='computer'

          6.       假如在這個表建一個由username+class+age三個列組成的索引。索引中的行是按username/class/age 的次序存放的,因此,索引中的行也會自動按username/class 的順序和username 的順序存放。這表示,即使在查詢中只指定username 值或只指定username class 的值,也可以利用此索引。因此,此索引可用來搜索下列的列組合:
              username,class,age

              username,class

              username

          不能使用不涉及左前綴的搜索。例如,如果classage 進行搜索,則不能使用該索引。如果要搜索某個用戶名以及某個年齡(索引中的列1和列3),則此索引不能用于相應值的組合。但是,可利用索引來尋找與該用戶名相符的行,以減少搜索范圍。

          7.       如果username+class這個索引是被定義為主鍵的話,這此時將不會出現上面那種情況。

          只要查詢條件中緊跟username這個查詢條件,則無論何種組合這個索引都能起作用

          例如:db2expln -d afa -o testsql1.txt -q "select * from sygjj_test_index where username=’aa’"

           

          探索查詢時會不會聯合使用由單個列組成的索引

                  利用下面這個語句,可探索是否在查詢時使用了sy_test_keysy_test_index2,由測試報告中可知該查詢使用這兩個索引

          可利用這句代碼進行測試,并觀看測試結果db2expln -d afa -o testsql1.txt -q "select * from sygjj_test_index where id='1' and age='20'"

          而且使用這種索引不會被select后面緊跟的字段所限制,只要查詢條件中包含idage,或包含它們兩個,索引都會起效果,由于建了這兩個索引之后,對查詢條件中包含它們兩個時索引會聯合使用,故可不必再建多一個由這兩個列組成的索引,因為當索引建得越多時,其所占的空間會越大,而且在插入或更新索引時的操作時間也會相應增加。

          測試報告如下:
           

          db2expln -d afa -o testsql1.txt -q "select * from sygjj_test_index where id='1' and age='20'"

           

           

          DB2 Universal Database Version 8.1, 5622-044 (c) Copyright IBM Corp. 1991, 2002

          Licensed Material - Program Property of IBM

          IBM DB2 Universal Database SQL Explain Tool

           

          ******************** DYNAMIC ***************************************

           

          ==================== STATEMENT ==========================================

           

                  Isolation Level          = Cursor Stability

                  Blocking                 = Block Unambiguous Cursors

                  Query Optimization Class = 5

           

                  Partition Parallel       = No

                  Intra-Partition Parallel = No

           

                  SQL Path                 = "SYSIBM", "SYSFUN", "SYSPROC", "AFA"

           

           

          SQL Statement:

           

           select *

           from sygjj_test_index

           where id='1'and age='20'

           

           

          Section Code Page = 1386

           

          Estimated Cost = 0.556049

          Estimated Cardinality = 0.040000

           

          Index ANDing

          | Optimizer Estimate of Set Size: 1

          | Index ANDing Bitmap Build Using Row IDs

          | | Optimizer Estimate of Set Size: 1

          | | Access Table Name = AFA.SYGJJ_TEST_INDEX ID = 2,31

          | | | Index Scan: Name = AFA.SY_TEST_KEY ID = 1

          | | | | Regular Index (Not Clustered)

          | | | | Index Columns:

          | | | | | 1: ID (Ascending)

          | | | #Columns = 0

          | | | Single Record

          | | | Fully Qualified Unique Key

          | | | #Key Columns = 1

          | | | | Start Key: Inclusive Value

          | | | | | | 1: '1'

          | | | | Stop Key: Inclusive Value

          | | | | | | 1: '1'

          | | | Index-Only Access

          | | | Index Prefetch: None

          | | | Isolation Level: Uncommitted Read

          | | | Lock Intents

          | | | | Table: Intent None

          | | | | Row : None

          | Index ANDing Bitmap Probe Using Row IDs

          | | Optimizer Estimate of Set Size: 1

          | | Access Table Name = AFA.SYGJJ_TEST_INDEX ID = 2,31

          | | | Index Scan: Name = AFA.SY_TEST_IDX2 ID = 3

          | | | | Regular Index (Not Clustered)

          | | | | Index Columns:

          | | | | | 1: AGE (Ascending)

          | | | #Columns = 0

          | | | #Key Columns = 1

          | | | | Start Key: Inclusive Value

          | | | | | | 1: '20'

          | | | | Stop Key: Inclusive Value

          | | | | | | 1: '20'

          | | | Index-Only Access

          | | | Index Prefetch: None

          | | | Isolation Level: Uncommitted Read

          | | | Lock Intents

          | | | | Table: Intent None

          | | | | Row : None

          Insert Into Sorted Temp Table ID = t1

          | #Columns = 1

          | #Sort Key Columns = 1

          | | Key 1: (Ascending)

          | Sortheap Allocation Parameters:

          | | #Rows     = 1

          | | Row Width = 12

          | Piped

          | Duplicate Elimination

          List Prefetch Preparation

          | Access Table Name = AFA.SYGJJ_TEST_INDEX ID = 2,31

          | | #Columns = 5

          | | Single Record

          | | Fetch Using Prefetched List

          | | | Prefetch: 1 Pages

          | | Lock Intents

          | | | Table: Intent Share

          | | | Row : Next Key Share

          | | Sargable Predicate(s)

          | | | #Predicates = 2

          | | | Return Data to Application

          | | | | #Columns = 5

          Return Data Completion

          由上面的測試報告中可看出,在該查詢語句中聯合使用了索引,你可用相應的測試方法,測試下其他相應的結論,在這我就不一一列舉了。
          posted on 2007-06-16 15:42 何建銳 閱讀(868) 評論(0)  編輯  收藏

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


          網站導航:
           
          主站蜘蛛池模板: 于田县| 新和县| 防城港市| 肥城市| 略阳县| 分宜县| 钟山县| 漯河市| 葫芦岛市| 新丰县| 澜沧| 太原市| 红桥区| 赤城县| 长子县| 武穴市| 余庆县| 门源| 奉节县| 遵义县| 胶州市| 霞浦县| 民和| 米脂县| 柘城县| 阳高县| 镇远县| 文水县| 新竹市| 双峰县| 阿拉善左旗| 福贡县| 连江县| 普定县| 通道| 内黄县| 延长县| 清河县| 浦江县| 溧阳市| 安义县|