More servicesWindows Live
HomeHotmailSpacesOneCare
 
MSN
Sign in
 
 
Spaces home  IncessantPhotosProfileFriendsMore Tools Explore the Spaces community
Updated 5/9/2007
Updated 6/18/2007
View space
rufu
View space
hujd
View space
炯炯-BLACK HOLE
View space
水晶心情

Incessant

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.考虑对是否可以对原有索引进行合并。

View more entries
 
There are no music lists on this space.