More servicesWindows Live
HomeHotmailSpacesOneCare
 
MSN
Sign in
 
 
Spaces home  IncessantPhotosProfileFriendsBlog Tools Explore the Spaces community

Blog

March 10

李连杰来淘宝了

今天,李连杰大驾光临到淘宝,真没想到啊,最郁闷的是昨天晚上我在做系统维护,今天11点才去公司上班,正好错过了。
啥也不说了,看下面的连接:
March 08

好久没有写了

有很多想法,写了好几篇草稿,我尝试了很多次,打开这个页面但总提不起劲贴出来,哎。
以后不会在这贴技术文章了,主要记录一些八卦,技术方面的东西都贴在团队blog上:http://www.taobaodba.com,欢迎大家光临和讨论。
January 28

说个笑话

快过年了,说个我编的笑话,晚上我正在厨房炒菜,那家伙跑进来一看是白菜豆腐,就喊着要吃肉。
我说:这大冷天你去买肉啊,凑合凑合着吃
那家伙说:不啊不啊,我要吃肉
我被吵得不行,指着手跟他说:你拿菜刀去,往我这割一块
那家伙说:不,我要吃猪肉
我说:哦,你等着,那我去拿菜刀。。。
 
都说瑞雪兆丰年,但愿持续的大雪能给来年带来好运,祝大家新年快乐!
January 23

这只是一场游戏

     基本上我是不看CBA的,晚上没什么事,正赶上央视5套直播福建队和江苏队的生死大战,那就看吧,也算是为福建队加加油,看完我就后悔了。比赛中主角不是双方的队员,而是裁判,裁判直接决定了球队的命运,关键时刻很明显的犯规别说是央视的解说员,就连我都看出来那是犯规,裁判就是看出不来,也就是这个判罚直接改变了局势,哎,算是白看了,没看到精彩的比赛,倒是看到了中国特色。我突然明白其实这只是游戏,游戏需要公平吗,玩的起你就玩,玩不起还是洗洗睡吧。
     以后尽量少看国内的比赛,没事多学学oracle,mysql,看什么电视呢?
January 08

Shared pool和library cache latch

Shared pool latch用来保护共享池内部结构,在分配和释放共享池时需要获得latch,在老化或释放空间时也需要 latch。Oracle9i之前,共享池内存结构是由单独的Shared pool latch保护,从9i开始,如果服务器有4个以上的cpu且shared_pool_size大于250M,Oracle会动态将共享池分为多个子池,最多可以达到7个sub pool。子池的数量也可以通过_kghdsidx_count参数来手动调整,每个子池有自己的结构,lru列表和shared pool latch。
查看Shared pool latch个数

SQL>select a.ksppinm,b.ksppstvl from x$ksppi a,x$ksppsv b where a.indx=b.indx and a.ksppinm='_kghdsidx_count';
KSPPINM          KSPPSTVL
----------------------------
_kghdsidx_count     2

SQL> select name,addr, child#, gets, misses  from v$latch_children where name = 'shared pool';
NAME                ADDR                 CHILD#       GETS     MISSES
-------------------------- ---------------- ---------- ---------- -
shared pool       070000000006D8E0          7          0          0
shared pool       070000000006D7E8          6          0          0
shared pool       070000000006D6F0          5          0          0
shared pool       070000000006D5F8          4          0          0
shared pool       070000000006D500          3          0          0
shared pool       070000000006D408          2    3477094        796
shared pool       070000000006D310          1    3599730        387
7 rows selected.

Oracle9i之前,过大的共享池会增加Shared pool latch的争用,因为共享池中的空闲内存被分类,并保存在大量的存储桶或空闲列表上,较大的共享池趋向于较长的空闲列表,进程在获得共享池内存池之前,需要持有latch扫描很长的空闲列表,这在高度并发的系统中可能会生产 latch争用,特别是一些不使用绑定变量的系统。

Library cache latch用来保护库高速缓存内部结构,Oracle进程在库高速缓存中修改,检查,锁定,加载或执行对象时都需要先获得latch,latch的数量通常大于cpu_count的最小质数。可以通过_kgl_latch_count参数进行手动更改。
查看Library cache latch的个数

SQL> select count(*)from v$latch_children where name='library cache';
  COUNT(*)
----------
        11

Library cache latch争用通常出现在具有高版本数的sql语句中,这些sql的表面字义是相同的如select * from test,但可能属于不同的底层如schema,因为这些sql具有相同的散列值和不同的版本,oracle需要去比较该语句和现有版本,这期间需要一直持有latch的,这可能会造成其他进程无法获得 latch。
查看高版本的sql语句:

select substr(sql_text,1,40),version_count
  2    from v$sqlarea where version_count > 10  order by version_count desc;

SUBSTR(SQL_TEXT,1,40)                      VERSION_COUNT
-------------------------------------
insert into AUCTION_SYSTEMLOG (                        172
update smon_scn_time set orig_thread=0,                 90

总的来说,shared pool和library cache争用主要出现在频繁的硬解析上,而过多的硬解析通常又和绑定变量存在关系,说了半天还是回到应用上,共享池的健壮性主要还是取决于应用的设计,而不不仅仅是参数的调整。

January 07

数据库又出问题了

     数据库又出事故了,其因来源于一个需求,某些行的标志位没有更新成功,需要我手动更新,这个需求涉及到3个大表的关联,一个表20万的结果集*表4G左右的数据*3G左右的数据关联,后面两个表基本上走full 全表扫描,也许你会问怎么结果集会这么大,怎么就没有驱动表呢,还真就没有驱动表,我也是第一次遇到。下面是我的思路
1.直接运行3个表关联,发觉根本不可能计算出数据来
2.以20万的结果集建临时表,关联其他两个表,nnd,还是出不了结果,后面两个的结果集太大,关键是要解决后面两个表的关联问题
3.建立20万数据临时表,把后面两个表用到的字段建成联合索引,看只走索引会快一点不,nnnd,以online建索引导致表被锁住了,应用被阻塞导致App挂掉了,我第一次用online建索引出现问题这种问题,晕。
    没有什么办法了,还是等到凌晨数据库不忙时在搞吧,慢就慢点,时间我还是有的。
January 03

如何建立合适的索引?

当你接手一个系统时,通常是从检查系统负载,cpu、内存使用率开始,查看statspack top5等待事件,逻辑读、物理读排名靠前的sql语句等等,然后进行初步的优化。而随着业务的深入了解,你开始从系统的角度去考虑据库设计,考虑应用实现的合理性,是否有更好的改进方案等。假设通过statspack报表找到了很耗资源的sql,表分析过,执行计划也是走索引,这种情况下怎么去判断 sql是优化的呢?
1.提取逻辑读排名靠前的sql
  6,813,699          336       20,278.9   10.1    66.72     80.45 3039661161
module: java@admin1 (tns v1-v3)
  select b.biz_source, count(*) as counts from     tb_hanzgs_de
tail a, tb_business_info b    where a.id = b.hanzgs_id
and a.status = :1      and a.deal_id = :2      and a.create_date
>= to_date(:3,'yyyy-mm-dd hh24:mi:ss')     and a.create_date < to
_date(:4,'yyyy-mm-dd hh24:mi:ss')        group by b.biz_source

2.查看执行计划
sql> explain plan for
  2  select b.biz_source, count(*) as counts
  3    from tb_hanzgs_detail a, tb_business_info b
  4   where a.id = b.hanzgs_id
  5     and a.status = :1
  6     and a.deal_id = :2
  7     and a.create_date >= to_date(:3, 'yyyy-mm-dd hh24:mi:ss')
  8     and a.create_date < to_date(:4, 'yyyy-mm-dd hh24:mi:ss')
  9   group by b.biz_source;
Explained.
SQL> @?/rdbms/admin/utlxpls
Plan hash value: 1387434542
-----------------------------------------------------------------------
id  | operation           |  name               | rows  | bytes | cost  |
-----------------------------------------------------------------------
  0 | select statement         |                          |  1 | 31 |215
  1 |  sort group by           |                          |  1 | 31 |215
  2 |   filter                 |                          |    |    |  
  3 |    nested loops          |                          |  1 | 31 |199
  4 |     table access by index rowid| tb_hanzgs_detail   |   1| 21 |198
  5 |      index range scan    | ind_tb_hanzgs_create     | 231|    |397
  6 |     index range scan     | ind_tb_business_info_biz |   1| 10 |1
-----------------------------------------------------------------------
索引定义
create index ind_tb_hanzgs_create  on tb_hanzgs_detail (create_date, deal_id,status, id)tablespace tbs_tb_ind online compute statistics;
3.查看语句执行时间
sql>select b.biz_source, count(*) as counts
  3    from tb_hanzgs_detail a, tb_business_info b
  4   where a.id = b.hanzgs_id
  5     and a.status = 1
  6     and a.deal_id = 0
  7     and a.create_date >= to_date(sysdate-10, 'yyyy-mm-dd hh24:mi:ss')
  8     and a.create_date < to_date(sysdate-5, 'yyyy-mm-dd hh24:mi:ss')
  9   group by b.biz_source;

biz_source     counts
---------- ----------
       102        712
       501       7881
       701       1465

3 rows selected.

elapsed: 00:00:17.03
sql> /

biz_source     counts
---------- ----------
       102        713
       501       7882
       701       1465

3 rows selected.

elapsed: 00:00:05.32

这个语句查询时间在5.3秒左右,对于查询频繁的oltp系统中,毫无疑问全表扫描的代价是最高的,按时间索引扫描数据效率也是很低的,毕竟一个时间段的数据也是不少的。考虑到上面sql正好使用时间列索引,如果status,rule_id列稀疏读很高的话,这些列建立索引性能应该会有很大的提高。
4.查看表数据分布
sql>  select status, count(*) as counts
  2     from tb_hanzgs_detail
  3    where create_date >= to_date(sysdate - 50, 'yyyy-mm-dd hh24:mi:ss')
  4      and create_date <  to_date(sysdate - 49, 'yyyy-mm-dd hh24:mi:ss') + 1
  5    group by status;
    status     counts
--------- ----------
         0          2
         1        286
         2       3567
         3     123477

根据随机抽取几天数据分布结构,这个表中97%以上数据的status都等于3,如果status为3的查询应该会走全表扫描,消耗大量资源,查询频繁的话DBA是不允许开发部署到生产系统的,数据库压力太大。而status不等于3的数据量很少很少,以status列来建立索引,性能应该会有很大的提高。分析完就可以尝试的进行优化了。
5.重新建立索引
create index ind_tb_hanzgs_de_sta on tb_hanzgs_detail (status, deal_id, create_date,id)tablespace tbs_tb_ind online compute statistics;
新执行计划
sql> explain plan for
  2  select b.biz_source, count(*) as counts
  3    from tb_hanzgs_detail a, tb_business_info b
  4   where a.id = b.hanzgs_id
  5     and a.status = :1
  6     and a.deal_id = :2
  7     and a.create_date >= to_date(:3, 'yyyy-mm-dd hh24:mi:ss')
  8     and a.create_date < to_date(:4, 'yyyy-mm-dd hh24:mi:ss') + 1
  9   group by b.biz_source;
explained.
elapsed: 00:00:00.01
14:11:48 sql> @?/rdbms/admin/utlxpls
------------------------------------------------------------------
id  | operation            |  name        | rows  | bytes | cost |
------------------------------------------------------------------
  0 | select statement     |                          |1 |31 |19 |
  1 |  sort group by       |                          |1 |31 |19 |
  2 |   filter             |                          |  |   |   |
  3 |    nested loops      |                          |1 |31 | 3 |
  4 |     index range scan | ind_tb_hanzgs_de_sta     |1 |21 | 4 |
  5 |     index range scan | ind_tb_business_info_biz |1 |10 | 1 |
------------------------------------------------------------------
6.重新执行该语句
sql>select b.biz_source, count(*) as counts
  3    from tb_hanzgs_detail a, tb_business_info b
  4   where a.id = b.hanzgs_id
  5     and a.status = 1
  6     and a.deal_id = 0
  7     and a.create_date >= to_date(sysdate-10, 'yyyy-mm-dd hh24:mi:ss')
  8     and a.create_date < to_date(sysdate-5, 'yyyy-mm-dd hh24:mi:ss')
  9   group by b.biz_source;

biz_source     counts
---------- ----------
       102        713
       501       7881
       701       1465

3 rows selected.

elapsed: 00:00:00.24
sql> /

biz_source     counts
---------- ----------
       102        713
       501       7882
       701       1465

3 rows selected.

elapsed: 00:00:00.23

调整后的查询时间在0.2秒左右,速度提高了100倍左右,我只是简单的把索引列位置调换一下,性能就有了很大提高,statspack看不到这条语句了。总的来说,索引不是说create就可以了,通常需要考虑以下几点。
1.结合实际的应用。
2.考虑索引列的数据分布,如果distinct值很少且数据分布均匀的话,可能就不适合放在联合索引的最前面。
3.考虑索引的大小,在字段长度32的列和长度为7的列上建立索引大小肯定是不一样的,索引越大扫描的代价就越高。
4.考虑索引列冗余,可能你在索引中多冗余一个小字段,select就只走索引而不需要去扫描原表的数据。
5.考虑索引对其他sql的影响,是否其他的sql也可以使用这个索引。
6.考虑对是否可以对原有索引进行合并。

January 01

2008年第一天

    看着同事一个个热情洋溢的总结,半天也没能回忆起我曾经做了些什么,我的2007年可以用两个“天堂”来形容,其一,我离开北京来到了人间天堂杭州,其二,我最最依赖的人去了天堂。从此,我的生活发生了很多改变,一夜之间仿佛看淡了很多事情。
    08年对我,我所在的团队,淘宝都会是个好年。淘宝交易额成倍成倍的增长,产品越来越完善;团队的博客正式开通了,技术越来越深厚,我们的目标是打造成全中国最优秀的dba团队;而我自己也会越来越好的。
            1.努力工作,享受生活
            2.深入了解oracle的各种实现机制,写出2-3篇有技术功底的文档
            3.学通mysql
            4.亲人朋友身体健康
            5.多旅游,多运动
    祝福我的亲人,我的朋友,祝福淘宝,祝福淘宝dba团队,也祝福你,欢迎访问和加入我们:http://www.taobaodba.com
December 19

Oracle Shared Servers需要关注什么

     对于oracle数据库性能调整,关注的总会是reponse time和wait time,共享服务器进程也不例外,我们需要通过视图收集数据来判断性能的好坏,参数设置是否合理。

1.Dispatcher
     v$dispatcher - general information about dispatcher processes
     v$dispatcher_rate - dispatcher processing statistics
To assess dispatcher performance, query the v$dispatcher_rate view and compare the current values with the maximums. If your present system throughput provides adequate response time and current values from this view are near the average and less than the maximum, then you likely have an optimally tuned shared server environment.
If the current and average rates are significantly less than the maximums, then consider reducing the number of dispatchers. Conversely, if current and average rates are close to the maximums, then you might need to add more dispatchers. A general rule is to examine v$dispatcher_rate statistics during both light and heavy system use periods. After identifying your shared server load patterns, adjust your parameters accordingly.

 

2.Shared servers
select decode(totalq, 0, 'no requests',wait/totalq || ' hundredths of seconds') "average wait time per requests"
   from v$queue
  where type = 'common';
 average wait time per request
 -----------------------------
 .090909 hundredths of seconds

From the result, you can tell that a request waits an average of 0.09 hundredths of a second in the queue before processing.
You can also determine how many shared servers are currently running by issuing the following query:
select count(*) "shared server processes"
  from v$shared_server
 where status != 'quit';

The result of this query could look like the following:
shared server processes
-----------------------
10

If you detect resource contention with shared servers, then first make sure that this is not a memory contention issue by examining the shared pool and the large pool. If performance remains poor, then you might want to create more resources to reduce shared server process contention.you can do this by modifying the optional server process initialization parameters
max_dispatchers
max_shared_servers
dispatchers
shared_servers

 

http://download.oracle.com/docs/cd/b19306_01/server.102/b14211/build_db.htm#g27214  

November 30

我这几年

      我读书那些年,大学生是多么渴望能进入联想,方正,清华同方,用友这些所谓的大公司,这些公司在学校名气很大,你想想,独栋的办公楼,楼顶挂着大大的方正大厦四个大字,中关村满地的方正科技的广告,你会觉得相当洋气,相当的自豪。 我很幸运,刚毕业有机会加入方正春元,能进入方正并不表示我有多大的能力,学习有多好,这完全是个巧合,方正春元当时急着招人,没面试两句就让我上班了。大公司的确有大公司的好处,公司会教你怎么做人,怎么做事,怎么学习,怎么跟客户打交道,每天提交工作日志,处理事情要遵守规范等等,我从中学到了很多东西,最重要的是,在方正我明白了我以后要去做什么。所以说,第一份工作的选择还是很重要的。
     由于个人原因我离开了方正,当时我对这个选择很犹豫,因为我预测不到将来会有什么变化,也不知道以后会不会后悔,当时我只是想去做专职数据库方面的工作,就来到了和合盛视这家sp公司,短信的网关程序还是很简单的,基本上不需要怎么维护,没有任何的压力,很轻松的。那时候一般10点之前是没什么人到公司的,公司也不考勤,请假说一下就可以了,随来随走,每天中午技术总监都要招呼我们cs两个小时。而且那时候sp很来钱,公司是不缺钱的,整个团队很活泼,很温馨,老板也舍得花钱,基本上每个月都要组织我们出去玩,去桂林,张家界,北京近郊,滑雪等等,那时候好像钱不是问题,最重要的是大家都高兴。不过,这种公司的结局是很容易预料到的,好日子总是短暂的,公司被掌中万维给兼并了,由于一些原因,我们公司的所有人都离职了,我在这个公司也就呆了7个月,现在能想起来的除了玩还是玩,每天的cs,还有我对面的yoyo每天总是在11点左右上班,正好能赶上中午饭和cs对决。
     第三家公司是263网络通信,很多在北京生活过的都应该上过263网络在线的,以前号称是第四大门户,现在虽然不做门户了,但是收入不会低于三大门户网站。因为已经有过一段dba的经历了,数据库大部分知识还是了解的,很顺利就通过公司的几次面试。263公司的管理比较混乱,权利斗争很严重,部门之间很难协调,我想这也是公司屡屡在很好的环境下却总错过机会的原因,公司眼光太短浅了,而我加入公司不到5个月,整个运营部门就被公司解散了,我又失业了,当时我倒是无所谓的,反正有补偿金拿,无所谓了,很多有同事在公司干了7年,三五年的比比皆是,把最好的光阴奉献给为了公司,但是职业化就是这样,说解雇就解雇,根本不会考虑别的。大概出来后4个月后,公司又邀请我回去工作,不过我已经根本不考虑了。
      经历了一年内两次的被辞退后,我进入了一家大sp公司,指云时代,主要负责报表这一块,我前任写的程序很差劲,基本上天天都要运行很长时间才能出结果,重要的报表都会有这,那问题,随着数据量的越来越大,到最后干脆就算不出来,后来他实在受不了就离职了。我刚开始接手工作非常困难,要先去了解业务,重新设计架构,重写所有的报表程序,重新做报表,后面是领导每天追着你要数据,加班加点,整整了用了我6个月的时间搭建出一套新的报表系统,很多时候我都觉得我做不了,我要放弃,不过最终还是被我熬出来了,写完之后后面的工作也就是修修补补,改造改造,还是蛮闲得,这套系统可以支持几亿的数据量计算,到现在为止也没有出过什么问题,我感到很自豪,的确,很多时候程序主要在于设计而不在于优化。
     在北京差不多四年了,我从刚开始的西北四环上班,后来到了北三环,东二环,再到北京的CBD,上班的地段越来越繁华,越来越像白领了。同时我渐渐开始厌倦了每天的挤公交车,堵车,厌倦了每天听着噪音入眠,厌倦了每天冬天光秃秃的风景和满手的静电,甚至已经厌倦了北京繁华,我总感觉到很疲惫,我知道这已经不是我要的生活了,我开始向往小城市,向往宁静悠闲的生活,我宁愿少挣一些钱,多一点点人情味,少一点冷漠,这时候正好有一个机会让我加入了taobao。
     工作上我总是很幸运的,我想感谢很多人,感谢我曾经的现在的所有同事,我的同学,我的亲人,谢谢你们的帮助,我会继续努力,踏踏实实的工作着,生活着。 
我的公司:
         方正春元         http://www.founder.com 
         和合盛视         http://www.go2joy.com
         263网络通信    http://www.net263.com       
         指云时代         http://www.sensky.com
         淘宝网            http://www.taobao.com
     有时候算算吓了一跳,短短几年,怎么在这么多家公司呆过呢,其实我是个很懒的人,甚至懒得去跳槽,但是很多时候你没有办法去决定一件事情,如果能在一个公司呆很长的时间,那也是种幸运。
     我哥以前说过,当我们很渺小的时候,要好好活着,不给社会造成负担就是对社会的一大贡献,那就好好活着吧!

91天了

     晚上怎么也睡不着,看着天花板想了很多事情,突然预感到今天是第100天了,又觉得不对,我在床上一个人算着,算了半天,28+30+31+1=100,好像是对的,算好日子觉得还是要写下来,我的记性越来越不好了,以前很多我应该去做的我确没去做过,很多应该要烙在我心里的东西我总忘掉,很多事情说不清是后悔还是遗憾,打开电脑后想想还是算的不对,我对着电脑比划了半天,终于算出是90才对,确切的时间应该是第90+1天,那第100天应该是2007年9月9号才对。
    老了,我自己能感觉的到,心真的老了,毫无准备的老去了,最简单的算法我愣是没有计算出来。
    我不敢称这个地方是我的博客,因为很多东西都是写给我自己看得,随便乱写的,只是为了以后回头时,看到这些内容能想起来点什么,想起一些我永远不能也不该忘却的东西。。。
November 28

杭州的电动车

     杭州电动车特别多,前段有报道说快到70万辆了,其实多少辆和我倒是没有多大的关系,我走我的路,让他们开电动车去吧。
     这年头你说走路安全吗,电动车也在人行道上跑着呢,开得一点还不比摩托车慢。今天早晨我在路边买早餐,正想着是买粽子还是包子好呢,一位愣头青叔叔骑电动车撞了过来,直接把我的自行车撂倒,还好,我没有什么事,这叔叔嘴巴念叨着,不好意思不好意思,没刹住刹住。我使劲的忍了再忍,跟叔叔说:你还是小心一点,别那天把大车给撞了,把自己给撞了,那就不好办了。tmd,这叫什么事,我好好的买我的早餐,碍谁谁了。。。
November 27

重新配置10g的OEM

最近两次数据库从9i升级到10g之后,oem就启动不起来,出现一大堆报错信息,需要重新配置一下。
配置过程:
[oracle10g@csdba1850 ~]$emca -repos create
[oracle10g@csdba1850 ~]$emca -config dbcontrol db
根据提示填入相应的信息,配置就成功了

启动oem:
[oracle10g@csdba1850 ~]$ emctl start dbconsole
TZ set to PRC
Oracle Enterprise Manager 10g Database Control Release 10.2.0.3.0 
Copyright (c) 1996, 2006 Oracle Corporation.  All rights reserved.
http://csdba1850:5500/em/console/aboutApplication
Starting Oracle Enterprise Manager 10g Database Control .......sh: line 1: 17631 Segmentation fault      /opt/oracle/product/10g/bin/emdctl status agent >/dev/null 2>&1
.................. started.
------------------------------------------------------------------
Logs are generated in directory /opt/oracle/product/10g/csdba1850_db10g18/sysman/log
October 19

如何使用dbms_stats分析统计信息?

Dbms_stats是oracle8i新增的程序包,它使统计数据的生成和处理更加方便,很多人都在推荐使用dbms_stats替代analyze,我倒是不怎么用过,记录一下

estimate_percent --估算抽样百分比
method_opt:for table --只统计表 for all indexed columns --只统计有索引的表列 for all indexes --只分析统计相关索引

--创建统计信息历史保留表
sql> exec dbms_stats.create_stat_table(ownname => 'scott',stattab => 'stat_table') ;

pl/sql procedure successfully completed

--导出整个scheme的统计信息
sql> exec dbms_stats.export_schema_stats(ownname => 'scott',stattab => 'stat_table') ;

pl/sql procedure successfully completed

--分析scheme
Exec dbms_stats.gather_schema_stats(
ownname => 'scott',
options => 'GATHER AUTO',
estimate_percent => dbms_stats.auto_sample_size,
method_opt => 'for all indexed columns ',
degree => 6 )

--分析表
sql> exec dbms_stats.gather_table_stats(ownname => 'scott',tabname => 'work_list',estimate_percent => 10,method_opt=> 'for all indexed columns') ;

pl/sql procedure successfully completed

--分析索引
SQL> exec dbms_stats.gather_index_stats(ownname => 'crm2',indname => 'IDX_ADM_PERMISSION_PID_MID',estimate_percent => '10',degree => '4') ;

pl/sql procedure successfully completed

--如果发现执行计划走错,删除表的统计信息
SQL>dbms_stats.delete_table_stats(ownname => 'scott',tabname => 'work_list') ;

pl/sql procedure successfully completed

--导入表的历史统计信息
sql> exec dbms_stats.import_table_stats(ownname => 'scott',tabname => 'work_list',stattab => 'stat_table') ;

pl/sql procedure successfully completed

--如果进行分析后,大部分表的执行计划都走错,需要导回整个scheme的统计信息
sql> exec dbms_stats.import_schema_stats(ownname => 'scott',stattab => 'stat_table');

pl/sql procedure successfully completed

--导入索引的统计信息
SQL> exec dbms_stats.import_index_stats(ownname => 'crm2',indname => 'IDX_ADM_PERMISSION_PID_MID',stattab => 'stat_table')

--检查是否导入成功
SQL> select table_name,num_rows,a.blocks,a.last_analyzed from all_tables a where a.table_name='WORK_LIST';

TABLE_NAME NUM_ROWS BLOCKS LAST_ANALYZED

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

WORK_LIST 4005 186 2007-10-12 15

SQL>

analyze和dbms_stats不同的地方:
analyze是同时更新表和索引的统计信息,而dbms_stats会先更新表的统计信息,然后再更新索引的统计信息,这里就有一个问题,就是当表的统计信息更新后,而索引的统计信息没有被更新,这时候cbo就有可能选择错误的plan
参考:
http://www.dbafan.com/blog/?p=114
http://zhouwf0726.itpub.net/post/9689/288301
http://download.oracle.com/docs/cd/B10501_01/server.920/a96533/stats.htm#33861

October 18

如何关闭统计信息自动分析?

      Oracle 10g中默认是对统计信息自动进行分析,每天22:00会启动一个scheduler job来来进行,自动分析并不是说每天都去分析一遍所有表,只是分析rows改变超过10%的表,这是合理的,只分析很少一部分表。当然任何新特性存在都会有一定缺陷,关键看我们怎么来用这个功能,至于是否要关闭自动分析,就要看你的需求和使用情况了。
 
--检查是否开启了自动分析
SQL> select t.owner,t.job_name,t.last_start_date,t.last_run_duration,t.next_run_date,t.comments
  2  from dba_scheduler_jobs t where t.comments like '%statistics collection%'
  3  ;
OWNER                          JOB_NAME                       LAST_START_DATE                                                                  LAST_RUN_DURATION                       NEXT_RUN_DATE                                                                    COMMENTS
------------------------------ ------------------------------ -------------------------------------------------------------------------------- --------------------------------------- -------------------------------------------------------------------------------- --------------------------------------------------------------------------------
SYS                            GATHER_STATS_JOB               17-OCT-07 10.00.03.137638 PM +08:00                                              +000000000 00:02:17.909439                                                                                               Oracle defined automatic optimizer statistics collection job
SQL>
 
--关闭自动分析
db158:/home/oracle>$sqlplus "/ as sysdba"
SQL*Plus: Release 10.2.0.3.0 - Production on Thu Oct 18 14:53:36 2007
Copyright (c) 1982, 2006, Oracle.  All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
SQL> exec dbms_scheduler.disable('SYS.GATHER_STATS_JOB') ;
PL/SQL procedure successfully completed.
 
--打开自动分析
SQL> exec dbms_scheduler.enable('SYS.GATHER_STATS_JOB') ;
PL/SQL procedure successfully completed.
 
具体的参考:
 
September 30

警示自己

    生产库上做任何操作,执行任何命令都要在头脑清醒的时候进行,谨慎再再谨慎,管了这么久的数据库,第一次有这样的体会,特发这句话来警示自己。不说别的了,祝大家10.1快乐!
August 30

杭州的物价

     我是不怎么买东西的,尤其是电子产品,mp3,相机,手机还有笔记本都是我哥给我带回来的,通常想自己买的,我哥总说,米国那边很便宜的,直接给你捎一个回来得了。记得年初T60在米国才795美元,合人民币6200左右,国内那时候怎么也得12000元,既然米国的东西这么实惠,我为什么还要在国内买呢?
     来杭州一小段时间了,感觉这地方物价还是蛮贵的,比较一下我最近买的:蒙牛早餐奶北京1.7元,经常是买6包送一包,杭州2.1元/包;蒙牛酸奶北京是8杯4.9元,经常还会送你两杯,杭州0.85*8=6.8元;北京花150元去家乐福能买个不错的自行车,杭州的超市基本上是290元了;房东没有提供电视,想在杭州花个300元买个凑合的电视,看来难啊,想想三年前大学同学在北京花了200元去组装了个不错的电视;家政服务杭州这边要12元/每小时,我在北京的时候是7块钱;当然,杭州的房租,电话费还是比北京便宜一点了。
     个人感觉杭州的物价水平还是蛮高的,搞的我买东西时总是顿了一下,怎么会这么贵呢。
August 25

没有借口

    今年弟弟参加高考,很遗憾没有考上理想的学校,平时我弟弟总是说,有些题目明明会做,就是给做错了,有些题目很简单,就是给选错了,我通常会告诉他,不要给自己找任何借口,错就是不会,就是做错了,好好检讨一下自己为什么会出现这种错误呢?
    昨天回答一套师傅出的有关sql知识的考题,这套题目出给开发人员的,我居然才答了55分,总以为这两年来写了不下几万行的sql编码,sql脚本对我来说应该不是什么问题,唉,真为自己是DBA感到羞耻。后来和老大核对了一遍,除了两个count(Null)的题目外,其他的我还是会做的。上大学以来,很多课程我都以为自己学的很通了,大学的考试也很很简单,我总只能是徘徊在70分左右,现在这个想象延续到工作上了,这个问题很严重,我得好好的检讨一下,不要有任何的借口。
   在这个高手横行的年代,我要更加努力一点。
August 02

library cache pin和lock的区别

     这个问题在面试中曾被问倒过,网络上能找到的资料也比较少,后来和yyxup,久游的一个puber讨论了半天,总算搞懂了一点 
     library cache object在内存中是分成2部分来存储的,第一部分是头信息,叫做handle,头信息里保存了指向具体保存该对象的地址,这个叫做heap.一个对象可能分为很多个heap要访问或者修改一个对象,首先要锁住其头信息,也就是handle,以防止其他session同时访问或者修改该对象,这是library cache lock要做的事情而当实际的访问或者修改对象的内容时,则要根据头信息去访问或者修改具体的heap的,那么也要防止其他session同时访问或者修改这些heap,所以对heap需要加library cache pin来保护(Nigoo的描述)
 
下面是我这一年来比较常用的几个脚本,基本上处理问题就靠这些sql混了,现记录下来
1.查看用户的session信息    
select * from v$session where username='ETL'
2.查看sid所对应的spid   
select se.SID,se.SERIAL#,pr.SPID from v$session se,v$process pr   where pr.ADDR=se.PADDR and se.SID=71
3.查看sid相应的执行sql
SELECT   sql_text    FROM v$sqltext a  WHERE a.hash_value = (SELECT sql_hash_value   FROM v$session b   WHERE b.SID = '48')  ORDER BY piece ASC
4.查看spid相应执行sql
SELECT /*+ ORDERED */ sql_text   FROM v$sqltext a  WHERE (a.hash_value, a.address) IN
         (SELECT DECODE(sql_hash_value, 0, prev_hash_value, sql_hash_value),
               DECODE(sql_hash_value, 0, prev_sql_addr, sql_address)
          FROM v$session b
         WHERE b.paddr =
               (SELECT addr FROM v$process c WHERE c.spid = '15125'))
 ORDER BY piece ASC
5.查看block所在的表空间
SELECT tablespace_name, segment_type, owner, segment_name   FROM dba_extents    WHERE file_id = 44  and 35245 between block_id AND block_id + blocks
6.产生批处理可以执行文件
begin
for i in -60..-1 loop
dbms_output.put_line('exec proc_tbl_sms_order_from(sysdate'||i||') ;');
end loop;
end ;
7.ALTER TABLE tbl_mt_succ DROP partition TBL_MT_SUCC_2006P9; --删除表分区
ALTER TABLE tbl_mt_succ ADD PARTITION TBL_MT_SUCC_2008P3 VALUES LESS THAN (TO_DATE('2008-04-01','YYYY-MM-DD') ) ; --增加分区
8.事务的uno
select used_ublk   from v$transaction   where addr = (select taddr   from v$session   where sid = (select sid from v$mystat where rownum = 1))
9.事务的redo
select my.SID, st.NAME, my.VALUE   from v$mystat my, v$statname st   where st.STATISTIC# = my.STATISTIC#  and st.NAME = 'redo size'
July 23

Index Full Scans和Fast Full Index Scans的区别

Index Full Scans

A full scan is available if a predicate references one of the columns in the index. The predicate does not need to be an index driver. A full scan is also available when there is no predicate, if both the following conditions are met:

  • All of the columns in the table referenced in the query are included in the index.
  • At least one of the index columns is not null.

A full scan can be used to eliminate a sort operation, because the data is ordered by the index key. It reads the blocks singly.

Fast Full Index Scans

Fast full index scans are an alternative to a full table scan when the index contains all the columns that are needed for the query, and at least one column in the index key has the NOT NULL constraint. A fast full scan accesses the data in the index itself, without accessing the table. It cannot be used to eliminate a sort operation, because the data is not ordered by the index key. It reads the entire index using multiblock reads, unlike a full index scan, and can be parallelized.

Fast full scan is available only with the CBO. You can specify it with the initialization parameter OPTIMIZER_FEATURES_ENABLE or the INDEX_FFS hint. Fast full index scans cannot be performed against bitmap indexes.

A fast full scan is faster than a normal full index scan in that it can use multiblock I/O and can be parallelized just like a table scan.

简单解释一下:
Index Full Scans单块,按照索引值顺序的读取,不需要排序
Fast Full Index Scans可以多块,并行的读取,从速度上来讲比正常的全索引扫描要快,但是因为可以是多块随机的读取,需要排序