组合索引使用错误案例

今天收到一个上线sql:

相关脚本如下:

索引结构:

create unique index PK_OSS_OPERATORSITE_ACT_DAY on OSS_OPERATORSITE_ACT_DAY (STATEDATE, PROVCODE, AREACODE, SITECODE, USERNUMBER, PORTALID);

merge into 条件是:

 Forall i In 1 .. l_Type_Usernumber.Count

                    Merge Into Oss_Operatorsite_Act_Day x Using Dual y

                                 On(x.Usernumber = l_Type_Usernumber(i) And

                                    x.Sitecode = l_Type_Sitecode(i) And

                                    x.Portalid = l_Type_Portalid(i) And

                  x.statedate = Ln_Statday)

 

从这个代码一看就知道问题所在了:

这里就可以看出来入口只有4个字段,主键是6个字段,一般只有merge的字段会大于或等于索引的字段:另外再试想下usernumber(手机号)其实就可以保证provcode(省份),areacode(地区)的唯一性了,这是在业务上保证的,一个手机号定了,那么他的省份和地区就固定下来了,我们优化的时候很多时候是可以从业务上去优化的。

另外其实这里还有一个问题,很明显索引建立的有问题,导致性能差别极大:

 

拿这个例子做个测试:

SQL> 

select * from OSS_OPERATORSITE_ACT_DAY_hch where STATEDATE=20121205 and usernumber ='13826093949' and SITECODE='0' and PORTALID=12; (和merge条件一致)

Execution Plan

----------------------------------------------------------

Plan hash value: 2326136338

-------------------------------------------------------------------------------------------------------------

| Id  | Operation                   | Name                          | Rows  | Bytes | Cost (%CPU)| Time     |

-------------------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT            |                               |     1 |   198 |     1   (0)| 00:00:01 |

|   1 |  TABLE ACCESS BY INDEX ROWID| OSS_OPERATORSITE_ACT_DAY_HCH  |     1 |   198 |     1   (0)| 00:00:01 |

|*  2 |   INDEX RANGE SCAN          | OSS_OPERATORSITE_ACT_DAY_IDX1 |     1 |       |     1   (0)| 00:00:01 |             --走索引1的开销是5个逻辑读:

-------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

   2 - access("STATEDATE"=20121205 AND "USERNUMBER"=13826093949 AND "SITECODE"='0' AND "PORTALID"=12)

Note

-----

   - dynamic sampling used for this statement

Statistics

----------------------------------------------------------

          0  recursive calls

          0  db block gets

          5  consistent gets

          0  physical reads

          0  redo size

       1091  bytes sent via SQL*Net to client

        492  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

          1  rows processed

我们如果走索引2:

select /*+index(a,OSS_OPERATORSITE_ACT_DAY_IDX2)*/* from OSS_OPERATORSITE_ACT_DAY_hch a where STATEDATE=20121205 

and usernumber ='13826093949' and SITECODE='0' and PORTALID=12;                     (和merge条件一致)

SQL> /

Execution Plan

----------------------------------------------------------

Plan hash value: 3005087471

-------------------------------------------------------------------------------------------------------------

| Id  | Operation                   | Name                          | Rows  | Bytes | Cost (%CPU)| Time     |

-------------------------------------------------------------------------------------------------------------

|   0 | SELECT STATEMENT            |                               |     1 |   198 |  1102   (1)| 00:00:14 |

|   1 |  TABLE ACCESS BY INDEX ROWID| OSS_OPERATORSITE_ACT_DAY_HCH  |     1 |   198 |  1102   (1)| 00:00:14 |

|*  2 |   INDEX RANGE SCAN          | OSS_OPERATORSITE_ACT_DAY_IDX2 |     1 |       |  1102   (1)| 00:00:14 |   --走索引2的一行的开销是3576个逻辑读

-------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

   2 - access("STATEDATE"=20121205 AND "SITECODE"='0' AND "USERNUMBER"=13826093949 AND "PORTALID"=12)

       filter("USERNUMBER"=13826093949 AND "SITECODE"='0' AND "PORTALID"=12)

Note

-----

   - dynamic sampling used for this statement

Statistics

----------------------------------------------------------

          0  recursive calls

          0  db block gets

       3576  consistent gets

          0  physical reads

          0  redo size

       1091  bytes sent via SQL*Net to client

        492  bytes received via SQL*Net from client

          2  SQL*Net roundtrips to/from client

          0  sorts (memory)

          0  sorts (disk)

          1  rows processed

 

 

性能差别非常大,请大家注意,一个是5个逻辑读,一个是3576,这仅仅是查询一行的开销主要的区别就是由于组合索引对查询索引字段的排列顺序导致的,

请大家以后注意这种情况:

1. 无需要的字段,不纳入组合索引列

2. 组合索引在创建的时候需要注意排列顺序(注:并非sql查询顺序)

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值