oracle高水位线的一次模拟测试

经常会遇到一个表,其中只有几条数据,结果查询一下表记录总数,发现特别的慢。这通常是由于oracle高水位线的问题引起的,见[1]。这样的表在实际应用中也不枚胜举,比如短信发送表,一次大批量发送了500万条短信,发完后表的记录全被删除(是delete,而不是truncate掉),之后查询该表会非常慢。原因在于delete操作并不会回收表被删除的空间,导致全表扫描时仍旧需要扫描那些记录已经全部被删除的块,导致速度和delete操作前没有变化。如果调用alter table XXX shrink SPACE收缩一下表,问题即解决。

 

本文即建了一个测试表(表有1个varchar2型的字段,长度为1024个byte)模拟了这个过程。先插入50万条记录,故表占用总空间约为500M(=500,000*1024)。之后进行delete操作,只保留其中一条记录。之后查询速度和delete前一样,收缩一下表之后,几个毫秒即即可返回结果。

  1. -- 创建测试表
  2. CREATE TABLE lcm_test(c1 INT, c2 VARCHAR2(1024));
  3. --TRUNCATE TABLE lcm_test;
  4. -- 统计表记录行数(没有任何索引,采用全表扫描)
  5. SELECT COUNT(*) FROM lcm_test;
  6. -- 收集统计信息
  7. ANALYZE TABLE lcm_test ESTIMATE STATISTICS;
  8. --察看表统计信息
  9. SELECT * 
  10. --SELECT COUNT(*)
  11. FROM all_tables 
  12. WHERE table_name = 'LCM_TEST';
  13. -- 插入测试数据
  14. DECLARE
  15. BEGIN
  16.     FOR i IN 1 .. 500000 LOOP
  17.         INSERT INTO lcm_test(c1, c2)
  18.         VALUES (i, lpad('a'1024'a'));
  19.         IF MOD(i, 1000) = 0 THEN
  20.             COMMIT;
  21.         END IF;
  22.     END LOOP;
  23.     COMMIT;
  24. END;
  25. -- 只保留一条记录
  26. DELETE FROM lcm_test WHERE c1 > 1;
  27. COMMIT;
  28. -- 统计表记录行数(没有任何索引,采用全表扫描)
  29. -- 由于delete并不会回收空间,故仍旧需要扫描记录已经全被删除的块
  30. -- 此时若收集lcm_test表的统计数据,与delete操作之前并没有变化
  31. SELECT COUNT(*) FROM lcm_test;
  32. -- 回收表被删除空间
  33. alter table lcm_test enable row MOVEMENT;
  34. alter table lcm_test shrink SPACE;
  35. -- 收缩之后,lcm_test只剩下一个块,全表扫描瞬间完成

[1] oracle高水位线问题 http://blog.chinaunix.net/u2/60332/showart_495441.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值