昨天我在写代码的时候,有一个要的数据我要去看一下到底数据是什么样子的,所以我就

select   *   from  tableName  这个表。但是执行了90多秒后,没有任何数据。我就一直很纳闷,为什么空表执行这么慢呢?然后百度了一些资料开始百度的资料说是因为delete这个表造成的碎屑空间,还是没有明白,不同的百度,后来知道了,原来是因为水位线的原因,那么下面截取一段在别人博客里面看到的资料。

      Oracle表段中的高水位线HWMhttp://www.cnblogs.com/linjiqin/archive/2012/01/15/2323030.html

在Oracle数据的存储中,可以把存储空间想象为一个水库,数据想象为水库中的水。水库中的水的位置有一条线叫做水位线,在Oracle中,这条线被称为高水位线(High-warter mark, HWM)。在数据库表刚建立的时候,由于没有任何数据,所以这个时候水位线是空的,也就是说HWM为最低值。当插入了数据以后,高水位线就会上涨,但是这里也有一个特性,就是如果你采用delete语句删除数据的话,数据虽然被删除了,但是高水位线却没有降低,还是你刚才删除数据以前那么高的水位。也就是说,这条高水位线在日常的增删操作中只会上涨,不会下跌。

下面我们来谈一下Oracle中Select语句的特性。Select语句会对表中的数据进行一次扫描,但是究竟扫描多少数据存储块呢,这个并不是说数据库中有多少数据,Oracle就扫描这么大的数据块,而是Oracle会扫描高水位线以下的数据块。现在来想象一下,如果刚才是一张刚刚建立的空表,你进行了一次Select操作,那么由于高水位线HWM在最低的0位置上,所以没有数据块需要被扫描,扫描时间会极短。而如果这个时候你首先插入了一千万条数据,然后再用delete语句删除这一千万条数据。由于插入了一千万条数据,所以这个时候的高水位线就在一千万条数据这里。后来删除这一千万条数据的时候,由于delete语句不影响高水位线,所以高水位线依然在一千万条数据这里。这个时候再一次用select语句进行扫描,虽然这个时候表中没有数据,但是由于扫描是按照高水位线来的,所以需要把一千万条数据的存储空间都要扫描一次,也就是说这次扫描所需要的时间和扫描一千万条数据所需要的时间是一样多的。所以有时候有人总是经常说,怎么我的表中没有几条数据,但是还是这么慢呢,这个时候其实奥秘就是这里的高水位线了。

那有没有办法让高水位线下降呢,其实有一种比较简单的方法,那就是采用TRUNCATE语句进行删除数据。采用TRUNCATE语句删除一个表的数据的时候,类似于重新建立了表,不仅把数据都删除了,还把HWM给清空恢复为0。所以如果需要把表清空,在有可能利用TRUNCATE语句来删除数据的时候就利用TRUNCATE语句来删除表,特别是那种数据量有可能很大的临时存储表。

在手动段空间管理(Manual Segment Space Management)中,段中只有一个HWM,但是在Oracle9iRelease1才添加的自动段空间管理(Automatic Segment Space Management)中,又有了一个低HWM的概念出来。为什么有了HWM还又有一个低HWM呢,这个是因为自动段空间管理的特性造成的。在手段段空间管理中,当数据插入以后,如果是插入到新的数据块中,数据块就会被自动格式化等待数据访问。而在自动段空间管理中,数据插入到新的数据块以后,数据块并没有被格式化,而是在第一次在第一次访问这个数据块的时候才格式化这个块。所以我们又需要一条水位线,用来标示已经被格式化的块。这条水位线就叫做低HWM。一般来说,低HWM肯定是低于等于HWM的。

(2)如何知道一个表的HWM?

a) 首先对表进行分析:

ANALYZE TABLE <tablename> ESTIMATE/COMPUTE STATISTICS;

b) SELECT blocks, empty_blocks, num_rows

FROM user_tables

WHERE table_name = <tablename>;

说明:

BLOCKS 列代表该表中曾经使用过得数据库块的数目,即水线。

EMPTY_BLOCKS 代表分配给该表,但是在水线以上的数据库块,即从来没有使用的数据块。

让我们以一个有28672行的BIG_EMP1表为例进行说明:

1) SQL> SELECT segment_name, segment_type, blocks

FROM dba_segments

WHERE segment_name='BIG_EMP1';

SEGMENT_NAME       SEGMENT_TYPE    BLOCKS

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

BIG_EMP1           TABLE           1024

1 row selected.

2) SQL> ANALYZE TABLE big_emp1 ESTIMATE STATISTICS;

Statement processed.

3) SQL> SELECT table_name,num_rows,blocks,empty_blocks

FROM user_tables

WHERE table_name='BIG_EMP1';

TABLE_NAME  NUM_ROWS  BLOCKS     EMPTY_BLOCKS

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

BIG_EMP1    28672     700        323

1 row selected.

注意:

BLOCKS + EMPTY_BLOCKS (700+323=1023)比DBA_SEGMENTS.BLOCKS少1个数据库块,这是因为有一个数据库块被保留用作segment header。DBA_SEGMENTS.BLOCKS 表示分配给这个表的所有的数据库块的数目。USER_TABLES.BLOCKS表示已经使用过的数据库块的数目。

4) SQL> SELECT COUNT (DISTINCT

DBMS_ROWID.ROWID_BLOCK_NUMBER(rowid)||

DBMS_ROWID.ROWID_RELATIVE_FNO(rowid)) "Used"

FROM big_emp1;

Used

----------

700

1 row selected.

5) SQL> delete from big_emp1;

28672 rows processed.

6) SQL> commit;

Statement processed.

7) SQL> ANALYZE TABLE big_emp1 ESTIMATE STATISTICS;

Statement processed.

8) SQL> SELECT table_name,num_rows,blocks,empty_blocks

FROM user_tables

WHERE table_name='BIG_EMP1';

TABLE_NAME  NUM_ROWS   BLOCKS   EMPTY_BLOCKS

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

BIG_EMP1    0          700      323

1 row selected.

9) SQL> SELECT COUNT (DISTINCT

DBMS_ROWID.ROWID_BLOCK_NUMBER(rowid)||

DBMS_ROWID.ROWID_RELATIVE_FNO(rowid)) "Used"

FROM big_emp1;

Used

----------

0 ----这表名没有任何数据库块容纳数据,即表中无数据

1 row selected.

10) SQL> TRUNCATE TABLE big_emp1;

Statement processed.

11) SQL> ANALYZE TABLE big_emp1 ESTIMATE STATISTICS;

Statement processed.

12) SQL> SELECT table_name,num_rows,blocks,empty_blocks

2> FROM user_tables

3> WHERE table_name='BIG_EMP1';

TABLE_NAME  NUM_ROWS  BLOCKS    EMPTY_BLOCKS

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

BIG_EMP1    0         0         511

1 row selected.

13) SQL> SELECT segment_name,segment_type,blocks

FROM dba_segments

WHERE segment_name='BIG_EMP1';

SEGMENT_NAME  SEGMENT_TYPE  BLOCKS

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

BIG_EMP1      TABLE         512

1 row selected.

注意:

TRUNCATE命令回收了由delete命令产生的空闲空间,注意该表分配的空间由原先的1024块降为512块。

为了保留由delete命令产生的空闲空间,可以使用TRUNCATE TABLE big_emp1 REUSE STORAGE.

用此命令后,该表还会是原先的1024块。

(3)修正ORACLE表的高水位线

在ORACLE中,执行对表的删除操作不会降低该表的高水位线。而全表扫描将始终读取一个段(extent)中所有低于高水位线标记的块。如果在执行删除操作后不降低高水位线标记,则将导致查询语句的性能低下。下面的方法都可以降低高水位线标记。

1.执行表重建指令 alter table table_name move;

(在线转移表空间ALTER TABLE 。。。 MOVE TABLESPACE 。。。ALTER TABLE 。。。 MOVE 后面不跟参数也行,不跟参数表还是在原来的表空间,move后记住重建索引。如果以后还要继续向这个表增加数据,没有必要move,只是释放出来的空间,只能这个表用,其他的表或者segment无法使用该空间)

2.执行alter table table_name shrink space; 注意,此命令为Oracle 10g新增功能,再执行该指令之前必须允许行移动alter table table_name enable row movement;

3.复制要保留的数据到临时表t,drop原表,然后rename临时表t为原表

4.emp/imp

5.alter   table  table_name  deallocate   unused

6.尽量truncate吧

Oracle查询数据表数据很少却很慢(查询空表很很耗时)相关推荐

  1. mysql 值很少的索引_关于 Mysql 字段值分布很少的字段要不要加索引的问题.

    我看到很多 mysql 索引的文章,都提到了,说如果某个字段的值分布范围很少(大量重复值),是不需要建立索引的. 但是我实际测试情况: user_type_id字段有索引: create table ...

  2. 两问表和三问表哪个更少_三问功能的表是什么?三问手表哪个品牌比较好?

    三问功能的表的制作成功,是机械制表工艺发展历程上的一个成就,在机械表有限的空间里面还要加入报时所需要的簧条装置,这只是简单的三问表,如果是要求音色比较悠扬动听的三问表,则还需要在此基础上加上三套或者更 ...

  3. 虽然这些代码很少,就几行,但却很牛逼!

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料! 作者:编程艺术思维 来源:urlify.cn/jqUree ...

  4. excel运行没反应_Excel数据很少文件却很大,问题出在哪里呢?两种方法轻松解决...

    经常和Excel打交道的小伙伴可能会有这样的困惑,一个Excel工作簿中的数据明明很少,文件所占的空间却很大. 打开这种Excel工作簿后,电脑CPU占用率瞬间飙升,甚至遇见工作簿没有响应的情况出现. ...

  5. 数据源架构模式之表数据入口

    数据源架构模式有四种:表数据之口,行数据入口,活动记录和数据映射器. 在了解它们之前,需对领域模型模式有一定的了解,可先参看 业务逻辑层之事务脚本与领域模型和业务逻辑层之表模块 一.概念 表数据入口( ...

  6. MySQL 新增表中的数据为另外一个或多个表的数据(业务场景:创建关系表,复制旧表数据到新表)

    问题 昨天同学问了我个问题 我想写个sql脚本,循环插入数据,数据是另一个表中的a.b字段 A表中的a.b字段数据,循环加入B表中a.b字段.就是这个意思 我问他为什么不用Java写,他说是数据维护, ...

  7. oracle导出dmp空表导不出来,如何解决Oracle11g使用dmp命令无法导出空表问题

    如何解决Oracle11g使用dmp命令无法导出空表问题 导出:exp  username/password@orcl file=路径 tables=(tb1)    //tables=(tb1)可有 ...

  8. Oracle 11gR2新特性--延迟段创建(Deferred Segment Creation)和exp不能导出空表

    Oracle 11gR2新特性--延迟段创建(Deferred Segment Creation)和exp不能导出空表 真题1. 什么是延迟段创建(Deferred Segment Creation) ...

  9. 为什么现在好多年轻人连1万都掏不出来,却觉得100万很少?

    ‍ ‍ 1.为什么现在好多年轻人连1万都掏不出来,却觉得100万很少? 其实年轻人觉的100万很少,恰恰是1万块钱都拿不出来的根源. 因为多数人对花钱的认知仍然停留在千儿八百,买一只口红300,不便宜 ...

  10. 相片打印机原理_激光照片打印机的原理 为什么很少人用激光照片打印机打印照片...

    激光照片打印机是利用激光扫描,在硒鼓上形成电荷潜影,然后吸附墨粉,再将墨粉转印到打印纸上,只不过黑白激光打印机只有一种黑色墨粉,而彩色激光打印机要使用黄.品.青.黑四种颜色的墨粉. 该图片由注册用户& ...

最新文章

  1. 浅述Oracle分布式事务概念
  2. python的中文翻译-再聊聊Python中文社区的翻译
  3. OpenCV cvLine
  4. 全局变量_Python函数中的全局变量与局部变量
  5. 【离散数学】论域和客体函数的区别
  6. Win7-VirsualBox下学习Ubuntu--初识ubuntu
  7. linux contos7防火墙加端口,Linux:centos7防火墙开放端口
  8. 麦子学院深度学习进阶课程题目纲要
  9. DiskGenius是一款硬盘分区及数据恢复软件
  10. ios appstore 上架应用被拒绝原因
  11. 在html中调用js函数
  12. PS2019工具介绍笔记(一)
  13. 方正飞鸿智能信息平台产品白皮书(一)
  14. Android Camera高级特性——手动对焦
  15. DL1 - Neural Networks and Deep Learning
  16. win10删除*某些设置由你的组织来管理
  17. 工银亚洲见证开户详细过程和攻略
  18. 曲线救国--为Chrome安装Edge浏览器插件
  19. 中建普联:大数据在工程造价中的应用
  20. 三网融合对即时通讯行业的影响

热门文章

  1. 知识普及:KB=Kb?
  2. IE,谷歌访问跨域问题
  3. nodejs addon
  4. std::move使用不当引起的copy elision
  5. 学了python还要学什么,学python先学什么
  6. Linux(Ubuntu)下WiFi网卡(intel ax201)驱动与Nvidia显卡驱动冲突的解决办法
  7. 下载excel表格后缀名为.do形式
  8. 大数据体系构建数据仓库
  9. 台电的平板大家慎重购买,售后堪忧
  10. direction和unicode-bidi