多年前dba面试的一道题

多年前参加dba面试时碰到的一道题,当时不会做,主考官也只是大致说了个思路,这么多年来一直想回答,却因为种种原因没有去答,整理笔记的时候,复又想起这道题...

对一张千万级的表,你要确定一个字段上,是否有某个值的记录,如果不使用count,有什么方法?

比如acct表,要确认是否有status=5的记录,不需要知道有多少条,只需要确认是否有该值的记录,可以如何实现?

答案如下:

DECLARE
  CURSOR curacct IS
    select status FROM acct;

  v_status acct.status%TYPE;

BEGIN
  --open方式引用cursor
  OPEN curacct;
  LOOP
    FETCH curacct
      INTO v_status;
    IF (curacct%NOTFOUND) THEN
      EXIT;
    END IF;
    if (v_status = 5) then
      dbms_output.put_line('there is acct that status=5');
      exit;
    end if;
  END LOOP;
  CLOSE curacct;
end;

大家知道,像status这种索引性很低的字段,通常索引的效率很低,即使加了索引,查询也不会快。用cursor去逐行扫描,只要有结果就返回,从某种意义上,效率是会更高的;最坏的情况是,没有匹配的值,那效率就会低于用count。

简单做个实验,对一张3千万级的表

当status取值存在并且靠前的时候,用cursor,0.016秒就可以得出结果;

而用count(*) ,条件status=5的话,要141秒;

当status取值不存在的时候,用cursor,要596秒

用count,是111秒;

当然,status的取值如果是一个枚举列表的话,就更加倾向于使用cursor了。



Link URL: http://echo.sharera.com/blog/BlogTopic/73699.htm

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26127/viewspace-676127/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/26127/viewspace-676127/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值