分区表用哪个级别的统计信息?

Posted by anysql on 2009-07-01

    这几天有几个分区表上的SQL执行计划不正常, 感觉上不应当, 已经设置了几个容易引起优化器选错执行计划的参数了.

ALTER SYSTEM SET OPTIMIZER_DYNAMIC_SAMPLING=0;
ALTER SYSTEM SET "_optim_peek_user_binds"=false;

    按照现行的表分析原则, 只统计了表的全局索引, 不统计表分区上的索引, 因为分区会有增减操作, 不是每个分区都有数据, 也没有定下来要经常分析表, 而是分析后如果不出问题就不再分析. 现在SQL走错了, 可能的原因有什么呢? 重新分析一下不行, 看了一下执行计划, 发现全表扫描的COST值很底, 估计是用了分区上的统计信息了, 于是手动将全局的统计信息复制到每一个分区上得以解决.

    为了得到原因, 回顾了一下当时的SQL, 发现有一个特征, 就是出问题的SQL都能定位到某个分区或某些分区, 今天就模拟了一下情况, 先只有全局统计信息. 首先用分区列范围查询, 去试了一下, 发现用的是分区级的统计信息.

SQL> select * from database_perf_statistics
  2  where day > sysdate - 100 and day < sysdate + 300;

----------------------------------------------------------------
| Id  | Operation                 | Cost (%CPU)| Pstart| Pstop |
----------------------------------------------------------------
|   0 | SELECT STATEMENT          |     3   (0)|       |       |
|*  1 |  FILTER                   |            |       |       |
|   2 |   PARTITION RANGE ITERATOR|     3   (0)|   KEY |   KEY |
|*  3 |    TABLE ACCESS FULL      |     3   (0)|   KEY |   KEY |
----------------------------------------------------------------

    然后全表扫描, 涉及所有的分区时, 用的是全局的统计信息.

SQL> select * from database_perf_statistics;
             
----------------------------------------------------------
| Id  | Operation           | Cost (%CPU)| Pstart| Pstop |
----------------------------------------------------------
|   0 | SELECT STATEMENT    |  2196   (1)|       |       |
|   1 |  PARTITION RANGE ALL|  2196   (1)|     1 |     4 |
|   2 |   TABLE ACCESS FULL |  2196   (1)|     1 |     4 |
----------------------------------------------------------

    再测试一个开包的查询条件, 发现用的也是分区的统计信息.

SQL> select * from database_perf_statistics where day > sysdate - 100;

---------------------------------------------------------------
| Id  | Operation                | Cost (%CPU)| Pstart| Pstop |
---------------------------------------------------------------
|   0 | SELECT STATEMENT         |     3   (0)|       |       |
|   1 |  PARTITION RANGE ITERATOR|     3   (0)|   KEY |     4 |
|*  2 |   TABLE ACCESS FULL      |     3   (0)|   KEY |     4 |
---------------------------------------------------------------

    重新设置了一下各分区的统计信息, 再验证一下上面的SQL的COST值, 就确定了是这个原因引起的, 需要更改一下我们的分析策略了.

DataReport的数据共享改进

Posted by anysql on 2009-06-30

    用oramon将数据库的主要负载信息收集到了性能数据库, 用DataReport去显示这些性能数据时, 发现要写很多个SQL语句, 要不同的列显示一次, 例如要显示三幅图片(平均Load值, 用户CPU消耗, SQL执行次数)就得执行三个SQL.

WEBCHART.QUERY_1=SELECT TIME, LOAD FROM DATABASE_LOAD ...
WEBCHART.QUERY_2=SELECT TIME, CPUUSR FROM DATABASE_LOAD ...
WEBCHART.QUERY_3=SELECT TIME, EXECS FROM DATABASE_LOAD ...

    其实DATABASE_LOAD是一个宽表, 可以一次查询出多个列的数据来, 几个图片可以共享一次查询的结果, 就可以减少数据库的执行次数, 提高页面访问速度. 如下所示, 只需要指定某个查询的SQL语句为减号.

WEBCHART.XCOL=TIME
WEBCHART.QUERY_1=SELECT TIME, LOAD, CPUUSR, EXECS
  FROM DATABASE LOAD ...
WEBCHART.YCOL_1=LOAD
WEBCHART.QUERY_2=-
WEBCHART.YCOL_2=CPUUSR
WEBCHART.QUERY_3=-
WEBCHART.YCOL_3=EXECS

    最近做了一次大的数据库改造, 用DataReport分析性能数据比较繁烦, 因此才注意到这个方面的性能提升.

oramon如何收集V$SYSTEM_EVENT数据?

Posted by anysql on 2009-06-25

    基于等待事件的性能调优方法, 自从提出来后就一直很管用, 很快就替换掉了根据命中率来调优的老方法. 当然oramon也同样关于等待事件的数据, 同样以10秒钟的频率计算出10秒内发生的等待事件数据, 并用如下格式保存.

06/25-15:23:44 206-49792:416125:83, 203-18279:89351:48, 157-8436:47502:56, 21-153:1438:93, 4-397:1360:34, 195-10382:906:0, 209-128:726:56, 210-26:514:197, 372-1409:24:0, 233-111:15:1, 207-1:10:100, 234-50:0:0, 152-2:0:0,
06/25-15:23:54 206-49756:414376:83, 203-18221:90461:49, 157-10301:52368:50, 4-448:1543:34, 209-161:1007:62, 21-180:973:54, 195-10376:926:0, 210-36:566:157, 372-1343:21:0, 207-2:13:65, 233-61:0:0, 234-50:0:0, 152-3:0:0,

    每一个时间点一行, 按总等待时间降序排列各个事件的数据, 单个事件的格式为"事件号-等待次数:等待时间:平均时长", 需要注意的是平均时长的单位是万分之一秒, 而不是千分之一秒(毫秒). 可以从目标库(不同版本会有差异)中根据事件号来查询等待事件名称.

SQL> select name from v$event_name where event#=206;

NAME
--------------------------------------------
db file sequential read

    象上面的例子中, 可以看到平均单块读的时间为8毫秒, 这个值可以用来评价OLTP系统的存贮响应时间. 利用10秒钟的等待事件数据, 帮我们发现了Oracle中超长log file sync等待的问题, 并成功绕过这个Bug, 有利于保持数据库系统的稳定运行.

oramon如何从V$SESSION收集性能数据?

Posted by anysql on 2009-06-25

    当我们真正遇到数据库的负载问题时, 一般都会有大量的活动会话,处理执行或是处于等待状态, 要解决问题或找出问题的根源, 就要知道那时这些活动会话在做些什到或等待什么? 在Oracle 10g中我们可以查询V$SESSION获得这些信息, 在Oracle 9i及更早的版本中, 则需要将V$SESSION和V$SESSION_WAIT关联起来.

    oramon中就记录了这些信息, 记录的数据如下, 格式为"事件号:SQL Hash Value-会话数". 表示在某个时间点有多少个会话在执行这个SQL, 这些会话处理什么样的等待状态.

......
10/30-20:02:37  205:2815233029:1, 372:4160993935:1
10/30-20:02:47  205:1623840268:1, 372:1569451005:1, 372:4160993935:1
10/30-20:02:57  205:374916427:1, 372:3179818757:1, 372:4160993935:1
10/30-20:03:07  205:1623840268:1, 372:860679981:1, 372:4160993935:1
10/30-20:03:17  372:4160993935:1
10/30-20:03:27  372:270817213:1, 372:4160993935:1
10/30-20:03:37  372:4160993935:1
......

    oramon每10秒执行一次查询并记录数据, 因此遇到问题时, 可以用记录的数据进行跟踪分析, 或进行事后分析. 为解决突发类的负载问题, 提供了有力的数据支持, 从我的经验中, 这些信息是非常有用的, 帮我找出了很多性能问题的根本原因, 从而切实解决了很多的问题.

Google被封, 苦了IT工作者

Posted by anysql on 2009-06-25

    Google被封, 苦了IT工作者, 没有了好的搜索来查找技术上面的资料, 预计中国的软件业会受到一定的影响. 百度有什么? 有的只是能让他赚钱的广告, 虚假的也好, 骗人的也好, 交钱就能被搜索到. 要找技术上的资料时, 百度上不管输入什么关键字, 前几页总有不相关的广告, 象街头的治牛皮癣广告, 在每个页面上都有, 而Google则能给出更多更准确更干净的搜索结果.

    Gmail被封, Google被封, flickr被封, WordPress被封, 不如有人网上建议的, 那么怕民众得到外面的信息, 直接断了中国到世界的网络出口算了, 搞一个彻底的局域网算了, 国外的公司要通过网络宣传产品, 请到中国来成立一个公司, 然后在局域网内受严格监控下架设一个站点, 还能让工商局多收点钱, 对GDP做些贡献.

    如果美国主动将到中国的网络断了? 或者一些大公司因为这个GFW直接放弃中国的市场, 我们真的就得到很多吗?

    大禹治水都重在疏导, 不在于堵, 不在于GFW. 一方面从小教育我们这方面的道理, 另一方面却在不停地封, 只是因为少部份人可以搜索到某些不太好的内容, 就认为所有的人都没有判断能力, 人民都是刁民, 从网上得到的最多的只是是一些很想掩别人的耳盗别人的铃的丑闻, 其实大部份年青人已经将下半生卖给房贷, 卖给银行了, 那就闲情去关注太多额外的东西呢. 有些事情过去十几年, 甚至二十年了, 还能怎么样呢? 更严重是因为权力和财富的线性关系引起的上上下下左左右右不同财团之间的内部争斗而已.

    说白了谁让你是IT工作者呢? 谁让你一定要用国外那些最先进的服务呢? 不如国内所有的IT工作者, 集体改行吧! 以后中国会多一个职业, 专门介绍国外互联网服务产品的讲师, 因为GFW无法亲自体验, 只能从声音中得到一点享受了.


Copyright © 2007 AnySQL.net. All rights reserved.