count(*)/count(列) 谁更快

–做个试验,看看到底谁更快?
drop table t purge;
create table t as select * from dba_objects;
–alter table T modify object_id null;
update t set object_id =rownum ;
set timing on
set linesize 1000
set autotrace on

select count(*) from t;
/
select count(object_id) from t;
/

–看来count(列)比count(*) 更快是谣传,明明是一样快嘛,真相是这样吗?
—NO!NO!NO!请继续往下看

–来来,建个索引看看
create index idx_object_id on t(object_id);
select count(*) from t;
/

select count(object_id) from t;
/

–哇,原来真的是用COUNT(列)比COUNT()要快啊,因为COUNT()不能用到索引,而COUNT(列)可以,真相真是如此吗?

alter table T modify object_id not null;

select count(*) from t;
/
select count(object_id) from t;
/

–看来count(列)和count()其实一样快,如果索引列是非空的,count()可用到索引,此时一样快!真相真是如此吗?

–性能比较首先要考虑写法等价,这两个语句根本就不等价!!!

最佳字段顺序(结论:越往后的列访问CPU开销大)

验证脚本1 (先构造出表和数据)
SET SERVEROUTPUT ON
SET ECHO ON
—构造出有25个字段的表T
DROP TABLE t;
DECLARE
l_sql VARCHAR2(32767);
BEGIN
l_sql := ‘CREATE TABLE t (‘;
FOR i IN 1..25
LOOP
l_sql := l_sql || ‘n’ || i || ’ NUMBER,’;
END LOOP;
l_sql := l_sql || ‘pad VARCHAR2(1000)) PCTFREE 10’;
EXECUTE IMMEDIATE l_sql;
END;
/
—-将记录还有这个表T中填充
DECLARE
l_sql VARCHAR2(32767);
BEGIN
l_sql := ‘INSERT INTO t SELECT ‘;
FOR i IN 1..25
LOOP
l_sql := l_sql || ‘0,’;
END LOOP;
l_sql := l_sql || ‘NULL FROM dual CONNECT BY level <= 10000’;
EXECUTE IMMEDIATE l_sql;
COMMIT;
END;
/

–验证脚本2(一次访问该表各字段验证)
execute dbms_stats.gather_table_stats(ownname=>user, tabname=>’t’)
SELECT num_rows, blocks FROM user_tables WHERE table_name = ‘T’;
–以下动作观察执行速度,比较发现COUNT(*)最快,COUNT(最大列)最慢
DECLARE
l_dummy PLS_INTEGER;
l_start PLS_INTEGER;
l_stop PLS_INTEGER;
l_sql VARCHAR2(100);
BEGIN
l_start := dbms_utility.get_time;
FOR j IN 1..1000
LOOP
EXECUTE IMMEDIATE ‘SELECT count(*) FROM t’ INTO l_dummy;
END LOOP;
l_stop := dbms_utility.get_time;
dbms_output.put_line((l_stop-l_start)/100);

FOR i IN 1..25
LOOP
l_sql := ‘SELECT count(n’ || i || ‘) FROM t’;
l_start := dbms_utility.get_time;
FOR j IN 1..1000
LOOP
EXECUTE IMMEDIATE l_sql INTO l_dummy;
END LOOP;
l_stop := dbms_utility.get_time;
dbms_output.put_line((l_stop-l_start)/100);
END LOOP;
END;
/

–结论:
–原来优化器是这么搞的:列的偏移量决定性能,列越靠后,访问的开销越大。由于count()的算法与列偏移量无关,所以count()最快。
–后面还有看图说话,看看结果输出的趋势图,就更了然了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值