首 页IT知识库翔宇问吧收藏内容
当前位置:翔宇亭IT乐园IT知识库数据库Oracle

ORACLE索引聚簇表的数据加载

减小字体 增大字体 作者:不详  来源:华军资讯  发布时间:2010-01-05 11:03:00

    上面的执行错误说明聚簇表无法在簇索引建立之前使用。

    首先我们通过先加载emp表,后加载dept表的方式。

    SQL> insert into dept

    2  select * from scott.dept;已创建4行。

    SQL> insert into emp

    2  select emp.*, '*' from scott.emp;已创建14行。

    然后做一个查询,通过dbms_rowid.rowid_block_number可以查看此数据所在的BLOCK ID,如果dept和emp存储的行数据不是一个BLOCK ID ,则标记一个'*'.查询结果如下:

    SQL> select dept_blk, emp_blk,
    2         case when dept_blk <> emp_blk then '*' end flag,
    3 deptno
    4 from (
    5  select dbms_rowid.rowid_block_number(dept.rowid) dept_blk,
    6         dbms_rowid.rowid_block_number(emp.rowid) emp_blk,
    7         dept.deptno
    8    from emp, dept 
    9   where emp.deptno = dept.deptno
   10 )
   11 order by deptno
   12 /

    DEPT_BLK EMP_BLK F DEPTNO

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

    85 86 * 10

    85 86 * 10

    85 87 * 10

    85 85 20

    85 87 * 20

    85 86 * 20

    85 85 20

    85 86 * 20

    85 85 30

    85 86 * 30

    85 85 30

    DEPT_BLK EMP_BLK F DEPTNO

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

    85 86 * 30

    85 85 30

    85 85 30

    已选择14行。

    我们发现,通过先插入emp数据,再插入dept数据,导致大部分的emp和dept的数据都不在一个block上,这不是我们使用聚簇索引的目的。
 
   方法二:

    先处理一下刚才插入的数据:

    SQL> truncate cluster emp_dept_cluster;

    truncate cluster emp_dept_cluster

    *

    第1行出现错误:

    ORA-02266:表中的唯一/主键被启用的外键引用

    SQL> alter table emp disable constraint emp_fk;

    表已更改。

    SQL> truncate cluster emp_dept_cluster;

    簇已截断。

    SQL> alter table emp enable constraint emp_fk;

    表已更改。

    然后使用以下的方式插入数据:

    SQL> begin

    2      for x in ( select * from scott.dept )

    3 loop

    4 insert into dept

    5          values ( x.deptno, x.dname, x.loc );

    6 insert into emp

    7          select emp.*, 'x' 8            from scott.emp 9           where deptno = x.deptno;

    10 end loop;

    11 end;

    12 /

    PL/SQL 过程已成功完成。

    执行上面统一的SQL。

    SQL> select dept_blk, emp_blk, 2         case when dept_blk <> emp_blk then '*' end flag,

    3 deptno

    4 from (

    5  select dbms_rowid.rowid_block_number(dept.rowid) dept_blk, 6         dbms_rowid.rowid_block_number(emp.rowid) emp_blk, 7         dept.deptno 8    from emp, dept 9   where emp.deptno = dept.deptno

    10 )

    11 order by deptno

    12 /

    DEPT_BLK EMP_BLK F DEPTNO

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

    85 85 10

    85 85 10

    85 85 10

    85 85 20

    85 85 20

    85 85 20

    85 86 * 20

    85 86 * 20

    86 86 30

    86 86 30

    86 86 30

    DEPT_BLK EMP_BLK F DEPTNO

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

    86 86 30

    86 87 * 30

    86 87 * 30

    已选择14行。

    咱们发现,大部分的数据都在同一个块中。原来这才是想聚簇表里添加数据的最佳方法。

    为什么会有这样的差别呢??

    当我们通过第一种方法时,有一个问题,由于dept表的行在聚簇中占用空间很小,但是剩余的空间确不能存一条dept的数据(应为我们添加了char(1000)了)。这样就会在那些聚簇 键块上导致过度的串链。Oracle会把包含这些信息的一组块串链或链接起来。如果同时加载对应一个给定聚簇键的所有数据,就能尽可能紧地塞满块,等空间 用完时再开始一个新块。

    四:什么时候不应该使用聚簇?

    1) 如果预料到聚簇中的表会大量修改:必须知道,索引聚簇会对DML的性能产生某种负面影响(特别是INSERT语句)。管理聚簇中的数据需要做更多的工作。

    2) 如果需要对聚簇中的表执行全表扫描:不只是必须对你的表中的数据执行全面扫描,还必须对(可能的)多个表中的数据进行全面扫描。由于需要扫描更多的数据,所以全表扫描耗时更久。

    3) 如果你认为需要频繁地TRUNCATE和加载表:聚簇中的表不能截除。这是显然的,因为聚簇在一个块上存储了多个表,必须删除聚簇表中的行。

    因此,如果数据主要用于读(这并不表示“从来不写”;聚簇表完全可以修改),而且要通过索引来读(可以是聚簇键索引,也可以是聚簇表上的其他索引),另外会频繁地把这些信息联结在一起,此时聚簇就很适合。

上一页  [1] [2] 

微信搜索“优雅的代码”关注本站的公众号,或直接使用微信扫描下面二维码关注本站公众号,以获取最新内容。

个人成长离不开各位的关注,你的关注就是我继续前行的动力。

知识评论评论内容只代表网友观点,与本站立场无关!

   评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
愿您的精彩评论引起共鸣,带来思考和价值。
用户名: 查看更多评论
分 值:100分 90分 80分 70分 60分 40分 20分
内 容:
验证码:
关于本站 | 网站帮助 | 广告合作 | 网站声明 | 友情连接 | 网站地图
本站部分内容来自互联网,如有侵权,请来信告之,谢谢!
Copyright © 2007-2023 biye5u.com. All Rights Reserved.