何建锐

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 何建锐 阅读(861) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: