Oracle-判断表上存在高水位线

表上高水位线:通常一个新建的表,1个8K的数据块存放100行记录,若表上经常插入删除操作,造成表的水位线很高。查看字典表user_tables,该表分配的数据块blocks很多,然而记录数num_rows确很少。实验证明:

1、查询表上的数据块大小
SQL> set linesize 1000;
SQL> col segment_name for a20
SQL> select SEGMENT_NAME,BYTES/BLOCKS/1024 K from user_extents where SEGMENT_NAME=TEST_EMP fetch first 1 rows only;

SEGMENT_NAME                  K
-------------------- ----------
TEST_EMP                      8
表上的数据块是8KB
2、新建表,查看一个数据块存放多少行数据
SQL> CREATE TABLE TEST_EMP
  2         (TEST_EMPNO NUMBER(4) not null,
  3  ENAME VARCHAR2(10),
  4  JOB VARCHAR2(9),
  5  MGR NUMBER(4),
  6  HIREDATE DATE,
  7  SAL NUMBER(7,2),
  8  COMM NUMBER(7,2),
  9  DEPTNO NUMBER(2) );

表已创建。

SQL> exec dbms_stats.gather_table_stats(ownname=>META,tabname=>TEST_EMP,estimate_percent=>10,method_opt=>for all indexed columns,cascade=>TRUE);

PL/SQL 过程已成功完成。
--收集表上的统计信息

SQL> select num_rows,blocks from user_tables where table_name=TEST_EMP;

  NUM_ROWS     BLOCKS
---------- ----------
         0          0
--新建表blocks为0,num_rows为0;
3、插入数据,多次插入
SQL>INSERT INTO TEST_EMP VALUES
(7369,SMITH,CLERK,7902,to_date(17-12-1980,dd-mm-yyyy),800,NULL,20);
INSERT INTO TEST_EMP VALUES
(7499,ALLEN,SALESMAN,7698,to_date(20-2-1981,dd-mm-yyyy),1600,300,30);
INSERT INTO TEST_EMP VALUES
(7521,WARD,SALESMAN,7698,to_date(22-2-1981,dd-mm-yyyy),1250,500,30);
INSERT INTO TEST_EMP VALUES
(7566,JONES,MANAGER,7839,to_date(2-4-1981,dd-mm-yyyy),2975,NULL,20);
INSERT INTO TEST_EMP VALUES
(7654,MARTIN,SALESMAN,7698,to_date(28-9-1981,dd-mm-yyyy),1250,1400,30);
INSERT INTO TEST_EMP VALUES
(7698,BLAKE,MANAGER,7839,to_date(1-5-1981,dd-mm-yyyy),2850,NULL,30);
INSERT INTO TEST_EMP VALUES
(7782,CLARK,MANAGER,7839,to_date(9-6-1981,dd-mm-yyyy),2450,NULL,10);
INSERT INTO TEST_EMP VALUES
(7788,SCOTT,ANALYST,7566,to_date(13-JUL-87,dd-mm-rr)-85,3000,NULL,20);
INSERT INTO TEST_EMP VALUES
(7839,KING,PRESIDENT,NULL,to_date(17-11-1981,dd-mm-yyyy),5000,NULL,10);
INSERT INTO TEST_EMP VALUES
(7844,TURNER,SALESMAN,7698,to_date(8-9-1981,dd-mm-yyyy),1500,0,30);
INSERT INTO TEST_EMP VALUES
(7876,ADAMS,CLERK,7788,to_date(13-JUL-87, dd-mm-rr)-51,1100,NULL,20);
INSERT INTO TEST_EMP VALUES
(7900,JAMES,CLERK,7698,to_date(3-12-1981,dd-mm-yyyy),950,NULL,30);
INSERT INTO TEST_EMP VALUES
(7902,FORD,ANALYST,7566,to_date(3-12-1981,dd-mm-yyyy),3000,NULL,20);
INSERT INTO TEST_EMP VALUES
(7934,MILLER,CLERK,7782,to_date(23-1-1982,dd-mm-yyyy),1300,NULL,10);
SQL> insert into test_emp
  2  select * from test_emp;

已创建 12 行。
4、再次统计信息,获取数据块及记录条数
SQL> exec dbms_stats.gather_table_stats(ownname=>META,tabname=>TEST_EMP,estimate_percent=>10,method_opt=>for all indexed columns,cascade=>TRUE);

PL/SQL 过程已成功完成。

SQL> select num_rows,blocks from user_tables where table_name=TEST_EMP;

  NUM_ROWS     BLOCKS
---------- ----------
    392500       2386
5、查看一个块存放多少记录
SQL> select f,b,count(*) from (select dbms_rowid.rowid_relative_fno(rowid) f,dbms_rowid.rowid_block_number(rowid) b from test_emp)
   group by f,b;
         F          B   COUNT(*)
---------- ---------- ----------
        14    2568672        170
        14    2568676        170
        14    2568677        169
已选择 2323 行。
--一个块存放169行左右的数据

至此,发现一个新建的表只有插入记录时,一个8K的数据块存放169行记录。test_emp表占用2386个数据块,记录行数392500。

若此时执行删除操作,再次收集表上的统计信息,就会看到记录条数为0时,test_emp表占用的数据块仍然是2386块。此时就造成了test_emp表上的高水位线

6、再次删除记录,查看test_emp占用的数据块
SQL> delete from test_emp purge; 已删除 393216 行。 SQL> exec dbms_stats.gather_table_stats(ownname=>META,tabname=>TEST_EMP,estimate_percent=>10,method_opt=>for all indexed columns,cascade=>TRUE); PL/SQL 过程已成功完成。 SQL> select num_rows,blocks from user_tables where table_name=TEST_EMP; NUM_ROWS BLOCKS ---------- ---------- 0 2386

故,8KB的数据块存放169行记录。若在字典表中看到test_emp表的num_rows与blocks差别太悬殊,则认为是高水位线。这是定性的方法,至于定量的还在研究中。

高水位线,解决办法:

https://www.cnblogs.com/handhead/p/13158177.html

Oracle-判断表上存在高水位线

上一篇:GoLang基础数据类型--->字典(map)详解


下一篇:Django连接MySQL数据库