首  页  论  坛 登  录  注  册 用户中心 风  格 论坛状态  会  员 最新贴子 灌水宝贝  搜  索 短消息 博客   社区监狱 聊天室 退出
  当前位置:  论坛首页 »  Oracle技术讨论 »  DBA日记讨论区
发新贴子 回复贴子 您是本帖第 644个阅读者     浏览上一篇主题    刷新本主题   浏览下一篇主题
4101/1页1
 主题:DBA日记第三部 像Oracle一样思考 4月1日 索引危机(1)不能修改应用的项目 [全部贴] [楼主贴] [打印] [收藏]
白鳝
客户
等级:超凡入圣
经验:82646
信用:6302
金币:122893
发贴:1234
精华:1
注册:2006-6-28
状态:离线
 (0)     (0)
版块置顶  锁定  置为精华  改变显示颜色 
白鳝的个人资料   发送短消息息给白鳝   发送电邮给白鳝   复制这个帖子   引用回复这个帖子   回复这个帖子      

 DBA日记第三部 像Oracle一样思考 4月1日 索引危机(1)不能修改应用的项目

41日 索引危机1不能修改应用的项目

刚才在会议室里和郭工一起讨论了这个项目,最近一两个月,郭工他们这套系统的CPU使用率增加了20%左右,白天业务高峰的时候,基本上CPU都在90-100%IDLE基本上都是0。郭工感觉到系统的风险很大,于是向领导李总做了汇报。于是李总就急忙叫我过来帮他们分析分析。

听郭工介绍,这套系统2周后将迎来每个月最繁忙的时段,从目前的情况来看,12CPU 24核的系统,r队列已经达到了40多,如果不做一些优化,可能很难安全渡过几天后的业务高峰。想要大幅度降低CPU的使用率,最好的办法是优化应用。

于是郭工把开发商负责维护系统的组长也叫到了会议室,商讨修改应用的事情。开发商一听说要修改SQL,马上把头摇得跟拨浪鼓似地。在2周时间内完成SQL修改工作,对于开发商来说,确实难度不小。经过协商,开发商认为索引的修改和PL/SQL存储过程的优化他们马上能够配合我们做,而需要修改程序的变更,他们必须上报给公司,走公司的变更流程,在2周内完成这个工作基本上不可能。开发商看样子是指望不上了,于是我决定把优化的重点放在索引的调整上。如果能找到几个buffer get较大的SQL,优化一下SQL,让CPU使用率下降10-15%,基本上能够完成任务了。

我采集了一下10点到11点的statspack报告:

Cache Sizes (end)

~~~~~~~~~~~~~~~~~

               Buffer Cache:     8,000M      Std Block Size:          8K

           Shared Pool Size:     3,200M          Log Buffer:     10,240K

Load Profile

~~~~~~~~~~~~                            Per Second       Per Transaction

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

                  Redo size:          2,596,262.30             60,116.45

              Logical reads:            572,843.36             13,264.19

              Block changes:             22,523.53                521.53

             Physical reads:              2,637.11                 61.06

            Physical writes:                672.75                 15.58

                 User calls:             21,920.49                507.57

                     Parses:              6,339.75                146.80

                Hard parses:                310.56                  7.19

                      Sorts:              1,714.43                 39.70

                     Logons:                  0.44                  0.01

                   Executes:              6,434.11                148.98

               Transactions:                 43.19

  % Blocks changed per Read:    3.93    Recursive Call %:      9.04

 Rollback per transaction %:    4.01       Rows per Sort:     48.64

Instance Efficiency Percentages (Target 100%)

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            Buffer Nowait %:   99.98       Redo NoWait %:     99.99

            Buffer  Hit   %:   99.60    In-memory Sort %:    100.00

            Library Hit   %:   97.61        Soft Parse %:     95.10

         Execute to Parse %:    1.47         Latch Hit %:     99.36

Parse CPU to Parse Elapsd %:   62.06     % Non-Parse CPU:     90.83

 Shared Pool Statistics        Begin   End

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

             Memory Usage %:  100.00  100.00

    % SQL with executions>1:   30.49   31.15

  % Memory for SQL w/exec>1:   34.11   34.20

Top 5 Timed Events

~~~~~~~~~~~~~~~~~~                                                     % Total

Event                                               Waits    Time (s) Ela Time

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

db file sequential read                         5,023,080      75,306    41.99

CPU time                                                       74,925    41.77

global cache cr request                         4,851,421       6,662     3.71

db file scattered read                            181,344       3,582     2.00

latch free                                      4,553,880       3,572     1.99

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

从报告上看,CPU TIME在所有的事件中排在第二位,基本上和db file sequential read差不多。另外NONE PARSE CPU只有90%左右,说明PARSE消耗的CPU也不少。不过只有2/3天的时间来做这个工作,这部分优化工作就暂时不考虑了。从等待事件上看:

                                                                   Avg

                                                     Total Wait   wait    Waits

Event                               Waits   Timeouts   Time (s)   (ms)     /txn

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

db file sequential read         5,023,080          0     75,306     15     32.3

global cache cr request         4,851,421      4,394      6,662      1     31.2

db file scattered read            181,344          0      3,582     20      1.2

IO性能不算太好,不过也还算凑合,不会有太大的性能影响。这次优化我们重点放在索引优化上,因此需要考虑的其他方面的问题较少,只要确保索引调整后,不会有TOP SQL出现执行计划变坏就行了。基于这样的考虑,整个优化工作就变得很简单了,首先挑出需要优化的SQL,然后分析是否可以通过调整索引进行优化,如果可以就做出一个索引调整方案,由开发商实施就可以了。一些较小的索引调整可以立即进行,如果索引的大小超过200M,就需要中午或者晚上业务较小的时间进行。

我在Statspack报告中查找逻辑读较大的SQL,看了一下排在第一位的是一条SQL,一小时执行了50万次,每次开销为1000多个BUFFER GET,查了一下执行计划,是通过一个索引做范围扫描,看样子也没有多大的问题,只是执行频率较高而已。排在第二位的是一条很简单的SQL

SELECT ORDER_ID ,

         NVL(PAYMENT_ID, -1) PAYMENT_ID,

         ACCT_ID,

         SERV_ID,

         ACTION,

         STATE ,

         TO_CHAR(CREATED_DATE,'YYYYMMDDHH24MISS'),

         TO_CHAR(STATE_DATE,'YYYYMMDDHH24MISS')   FROM A_XXX

         WHERE NVL(PAYMENT_ID,-1)>=:lPaymentID    AND STATE=:sState  ORDER BY

         NVL(PAYMENT_ID, -1), CREATED_DATE

这条SQL每次访问的BUFFER GET也只有不到2500,不过访问的次数也不少,有56万次。实际上这条SQL的写法是有问题的,我查了一下PAYMENT_ID字段上是有索引的,不过由于使用了NVL函数,导致了这个索引无法使用。实际上来说PAYMENT_ID是一个肯定大于0的字段,而在该字段上有一个>的过滤条件,因此满足该条件的记录PAYMEN_ID是肯定不为空的,所以如果把NVL函数去掉,改为:

SELECT ORDER_ID ,

         NVL(PAYMENT_ID, -1) PAYMENT_ID,

         ACCT_ID,

         SERV_ID,

         ACTION,

         STATE ,

         TO_CHAR(CREATED_DATE,'YYYYMMDDHH24MISS'),

         TO_CHAR(STATE_DATE,'YYYYMMDDHH24MISS')   FROM A_XXX

         WHERE PAYMENT_ID>=:lPaymentID    AND STATE=:sState  ORDER BY

         PAYMENT_ID, CREATED_DATE

从语义上来看,这两条SQL是完全等价的。因为PAYMENT_ID字段是十分常用的,因此PAYMENT_ID上的索引必须保留,因此这条SQL最佳的优化方案是修改程序,去掉PAYMENT_ID上的NVL函数。我和开发商沟通了一下,他们也认为这是开发人员的一个错误,这个NVL是可以去掉的,不过修改程序的审批和测试流程十分复杂,短期内很难实施,最好能有其他解决方案。如果要找其他解决方案,其他的方案就只能考虑在NVL(PAYMENT_ID,-1)上创建函数索引了。根据开发人员的介绍,这个SQL是查询PAYMENT_ID大于某个值的未处理过的记录的数量,STATE的值只有5/6个选择性一般。开发人员帮我找了一个PAYMENT_ID,我通过SELECT COUNT(*) FROM A_XXX WHERE PAYMENT_ID>:PID查了一下,满足大于PAYMENT_ID的记录大约占整个表的1/15。于是我再加上STATE的过滤条件进行查询,发现查出的记录综述占整个表的1/60。在这种情况下,创建NVL(PAYMENT_ID)+STATE的索引,效果比创建PAYMENT_ID的单列索引要好的多。A_XXX表的总记录数为200多万条,只要在业务不忙的时候,创建索引对系统影响不大。于是我建议中午的时候在这张表上创建这个索引。

中午的时候,开发商创建了这个复合索引。我吃完饭回到办公室是下午1:30,看了看系统的负载情况,CPU使用率只有50%左右。我知道这不可能是刚才那个索引的功劳,可能是中午很多营业厅都没什么业务。我做了一个STATSPACK6SNAP,生成了一份STATSPACK报告,看到这条SQL在半小时里执行了2万次不到,平均每次执行的buffer get的数量是1500左右,比刚才还是有明显的下降的,应该是执行计划出现了改变。为了确认这一点,我对这条SQL做了一个sprepsql,在SQL报告中,我明确的看到确实SQL执行的时候使用了新建的索引。

下午3-5点是下午的业务高峰期。确实2点半之后,系统负载就在不断的上升,不过CPU使用率一直在80%左右徘徊。我心中难免有些喜悦,难道刚才那个索引居然能取得这么好的效果?

310分左右,CPU使用率再次突破了90%,几分钟后,达到了95%330分左右,IDLE终于消失了。虽然我有点失望,不过这也在我的预料之中,想通过一两个索引达到优化的目的,是不太现实的。这套系统中,还有更多的工作需要做。

----------------------------------------------
blog:http://blog.oraclefans.cn/baishan1
xuj@justdb.cn
http://www.justdb.cn
IP:您无权察看 2010-6-6 13:36:00
  楼主   顶端
lijun110128
等级:初入江湖
经验:196
信用:56
金币:2544
发贴:4
精华:0
注册:2009-10-21
状态:离线
 (0)     (0)
lijun110128的个人资料   发送短消息息给lijun110128   发送电邮给lijun110128   复制这个帖子   引用回复这个帖子   回复这个帖子   

 回复:DBA日记第三部 像Oracle一样思考 4月1日 索引危机(1)不能修改应用的项目
学习了!!
IP:您无权察看 2010-6-6 23:12:06
  2  楼   顶端
netpinaster
等级:初入江湖
经验:105
信用:15
金币:385
发贴:0
精华:0
注册:2009-5-8
状态:离线
 (0)     (0)
netpinaster的个人资料   发送短消息息给netpinaster   发送电邮给netpinaster   复制这个帖子   引用回复这个帖子   回复这个帖子   

 回复:DBA日记第三部 像Oracle一样思考 4月1日 索引危机(1)不能修改应用的项目
白老大, 
Shared Pool Statistics        Begin   End

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

             Memory Usage %:  100.00  100.00
是不是说明shared pool的内存配置需要改善?导致sql的解析增加?
IP:您无权察看 2010-6-7 9:16:29
  3  楼   顶端
白鳝
客户
等级:超凡入圣
经验:82646
信用:6302
金币:122893
发贴:1234
精华:1
注册:2006-6-28
状态:离线
 (0)     (0)
白鳝的个人资料   发送短消息息给白鳝   发送电邮给白鳝   复制这个帖子   引用回复这个帖子   回复这个帖子      

 回复:DBA日记第三部 像Oracle一样思考 4月1日 索引危机(1)不能修改应用的项目
这个案例重点谈的是索引优化,这部分内容就不考虑了。这个案例里SHARED POOL是有偏小的问题,文中也提到了:
另外NONE PARSE CPU只有90%左右,说明PARSE消耗的CPU也不少。不过只有2/3天的时间来做这个工作,这部分优化工作就暂时不考虑了。从等待事件上看:
----------------------------------------------
blog:http://blog.oraclefans.cn/baishan1
xuj@justdb.cn
http://www.justdb.cn
IP:您无权察看 2010-6-7 10:44:53
  4  楼   顶端
4101/1页1
页面运行: 6391 毫秒

Powered by CWBBS 2.1  © 2005-2006 Cloud Web Soft
  Email:webmaster@justdb.cn