高水位线为什么不下降会影响全表扫描的性能,为什么删除数据时高水位线不自动下降呢?

解决方案 »

  1.   

    oracle在全表扫描的时候会扫描高水位线以下所有的数据块,如果你原来的数据占了10000个数据块,后来删除大部分数据之后只占用了1000个数据块,那么HWM还是在10000个数据块的地方,全表扫描会扫10000个块。删除数据HWM为什么不会下降,这个问题貌似没有一个很明确的答案。truncate表之后HWM才会降下来。
      

  2.   

    删除数据HWM为什么不会下降,取决于数据库的实现策略。如果要它下降,必然会导致删除数据的效率进一下降。这是一种权衡。
      

  3.   

    如果要使hwm下降,可以执行alter table t move。
      

  4.   

    删除数据HWM为什么不会下降,取决于数据库的实现策略。如果要它下降,必然会导致删除数据的效率进一下降。这是一种权衡。楼上这位说的有道理.为了使删除快速,不必重新整理,只能是高位线上了.
      

  5.   

    先试试purge recyclebin;
    或者,运行下面的存储过程,把输出的sql跑一遍,注意修改表空间名称
    set serveroutput on;DECLARE
      type SQL_COLL IS TABLE OF VARCHAR2(4000);
      v_sql_coll       SQL_COLL;
      v_src_tablespace varchar2(4000);
      v_des_tablespace varchar2(4000);
      v_start          NUMBER;
    BEGIN
      v_src_tablespace := 'USERS';
      v_des_tablespace := 'USERS';  --移动表
      select 'alter table ' || owner || '.' || table_name ||
             ' move tablespace ' || v_des_tablespace || ' ;' bulk collect
        into V_SQL_COLL
        from dba_tables
       where tablespace_name = v_src_tablespace
       order by 1;
      if V_SQL_COLL.count > 0 then
        for i in V_SQL_COLL.first .. V_SQL_COLL.last loop
          v_start := DBMS_UTILITY.get_time;
          dbms_output.put_line(V_SQL_COLL(i));
        end loop;
      end if;
    END;
    /DECLARE
      type SQL_COLL IS TABLE OF VARCHAR2(4000);
      v_sql_coll       SQL_COLL;
      v_src_tablespace varchar2(4000);
      v_des_tablespace varchar2(4000);
      v_start          NUMBER;
    BEGIN
      v_src_tablespace := 'USERS';
      v_des_tablespace := 'USERS';  --重建索引
      select 'alter index ' || owner || '.' || index_name ||
             ' rebuild tablespace ' || v_des_tablespace || ' ;' bulk collect
        into V_SQL_COLL
        from dba_indexes
       where tablespace_name = v_src_tablespace
         and index_type != 'LOB'
       order by 1;
      if V_SQL_COLL.count > 0 then
        for i in V_SQL_COLL.first .. V_SQL_COLL.last loop
          dbms_output.put_line(V_SQL_COLL(i));
        end loop;
      end if;
    END;
    /DECLARE
      type SQL_COLL IS TABLE OF VARCHAR2(4000);
      v_sql_coll       SQL_COLL;
      v_src_tablespace varchar2(4000);
      v_des_tablespace varchar2(4000);
      v_start          NUMBER;
    BEGIN
      v_src_tablespace := 'USERS';
      v_des_tablespace := 'USERS';  --移动大字段
      select 'alter table ' || owner || '.' || table_name ||
             ' move tablespace || v_des_tablespace || lob (' || column_name ||
             ') store as (tablespace ' || v_des_tablespace ||') ;' bulk collect
        into V_SQL_COLL
        from dba_lobs
       where tablespace_name = v_src_tablespace
       order by 1;
      if V_SQL_COLL.count > 0 then
        for i in V_SQL_COLL.first .. V_SQL_COLL.last loop
          dbms_output.put_line(V_SQL_COLL(i));
        end loop;
      end if;
    END;
    /
      

  6.   

    在Oracle数据的存储中,可以把存储空间想象为一个水库,数据想象为水库中的水。水库中的水的位置有一条线叫做水位线,在Oracle中,这条线被称为高水位线(High-warter , HWM)。在数据库表刚建立的时候,由于没有任何数据,所以这个时候水位线是空的,也就是说HWM为最低值。当插入了数据以后,高水位线就会上涨,但是这里也有一个特性,就是如果你采用delete语句删除数据的话,数据虽然被删除了,但是高水位线却没有降低,还是你刚才删除数据以前那么高的水位。也就是说,这条高水位线在日常的增删操作中只会上涨,不会下跌。
    下面我们来谈一下Oracle中Select语句的特性。Select语句会对表中的数据进行一次扫描,但是究竟扫描多少数据存储块呢,这个并不是说数据库中有多少数据,Oracle就扫描这么大的数据块,而是Oracle会扫描高水位线以下的数据块。现在来想象一下,如果刚才是一张刚刚建立的空表,你进行了一次Select操作,那么由于高水位线HWM在最低的0位置上,所以没有数据块需要被扫描,扫描时间会极短。而如果这个时候你首先插入了一千万条数据,然后再用delete语句删除这一千万条数据。由于插入了一千万条数据,所以这个时候的高水位线就在一千万条数据这里。后来删除这一千万条数据的时候,由于delete语句不影响高水位线,所以高水位线依然在一千万条数据这里。这个时候再一次用select语句进行扫描,虽然这个时候表中没有数据,但是由于扫描是按照高水位线来的,所以需要把一千万条数据的存储空间都要扫描一次,也就是说这次扫描所需要的时间和扫描一千万条数据所需要的时间是一样多的。所以有时候有人总是经常说,怎么我的表中没有几条数据,但是还是这么慢呢,这个时候其实奥秘就是这里的高水位线了。
    那有没有办法让高水位线下降呢,其实有一种比较简单的方法,那就是采用TRUNCATE语句进行删除数据。采用TRUNCATE语句删除一个表的数据的时候,类似于重新建立了表,不仅把数据都删除了,还把HWM给清空恢复为0。所以如果需要把表清空,在有可能利用TRUNCATE语句来删除数据的时候就利用TRUNCATE语句来删除表,特别是那种数据量有可能很大的临时存储表。
      

  7.   

    只知道
    delete不降
    truncate降
    再不就drop table
    再    create table 
      

  8.   

    在oracle concepts中有提到:
    In general, the extents of a segment do not return to the tablespace until you drop the schema object whose data is stored in the segment (using a DROP TABLE or DROP CLUSTER statement). Exceptions to this include the following:
    The owner of a table or cluster, or a user with the DELETE ANY privilege, can truncate the table or cluster with a TRUNCATE...DROP STORAGE statement. 
    A database administrator (DBA) can deallocate unused extents using the following SQL syntax:ALTER TABLE table_name DEALLOCATE UNUSED; 
    Periodically, Oracle deallocates one or more extents of a rollback segment if it has the OPTIMAL size specified. 
     一般来说,在用户将一个段对应的方案对象移除(使用 DROP TABLE 或 DROP CLUSTER 语句)之前,此段的数据扩展(extent)不会被回收到表空间(tablespace)中,但是以下情况例外:
    表,簇表的所有者(owner)或拥有 DELETE ANY 权限的用户, 可以使用 TRUNCATE...DROP STORAGE 语句将表,簇表的数据清除 
    DBA 可以使用以下语法收回一个段中未使用的数据扩展:
    ALTER TABLE table_name DEALLOCATE UNUSED; 如果用户为回滚段(rollback segment)设定了 OPTIMAL 参数,Oracle将周期性地从其中回收数据扩展。 
     
    When extents are freed, Oracle modifies the bitmap in the datafile (for locally managed tablespaces) or updates the data dictionary (for dictionary managed tablespaces) to reflect the regained extents as available space. Any data in the blocks of freed extents becomes inaccessible.
    当数据扩展(extent)被释放后,Oracle修改数据文件(datafile)中的位图(bitmap)(对于本地管理的表空间)或更新数据字典(对于数据字典管理的表空间),将回收的数据扩展视为可用空间。被释放的数据扩展中的数据无法继续访问。这可以说明为什么高水位线不下降吧
      

  9.   

    对机器中的文件删除时 直接delete为何不彻底删除而是放到回收站里呢,并且占用的空间还不释放。
    为何shift+delete却会彻底删除并会释放空间呢?^_^,一样的道理