Apress.Expert.Oracle.Database.Architecture.9i.and.10g.Programming.Techniques.and.Solutions.Sep.2005

rekharaghuram
from rekharaghuram More from this publisher
05.11.2015 Views

CHAPTER 10 ■ DATABASE TABLES 373 bytes). When it came time to load up the EMP rows, we might have found that some of the departments had many more than 1,024 bytes of data. This would cause excessive chaining on those cluster key blocks. Oracle would chain, or link together, a list of blocks to contain this information. By loading all of the data for a given cluster key at the same time, we pack the blocks as tightly as possible and start a new block when we run out of room. Instead of Oracle putting up to seven cluster key values per block, it will put as many as can fit. A quick example will show the difference between these two approaches. We’ll add a large column to the EMP table: a CHAR(1000). This column will be used to make the EMP rows much larger than they are now. We’ll load the cluster tables in two ways: we’ll load DEPT and then EMP. The second time, we’ll load by department number: a DEPT row, then all the EMP rows that go with it, and then the next DEPT. We’ll look at the blocks each row ends up on, in the given case, to see which one best achieves the goal of co-locating the data by DEPTNO. Our EMP table looks like this: ops$tkyte@ORA10GR1> create table emp 2 ( empno number primary key, 3 ename varchar2(10), 4 job varchar2(9), 5 mgr number, 6 hiredate date, 7 sal number, 8 comm number, 9 deptno number(2) references dept(deptno), 10 data char(1000) 11 ) 12 cluster emp_dept_cluster(deptno) 13 / Table created. When we load the data into the DEPT and the EMP tables, we see that many of the EMP rows are not on the same block as the DEPT row anymore (DBMS_ROWID is a supplied package useful for peeking at the contents of a row ID): ops$tkyte@ORA10GR1> insert into dept 2 select * from scott.dept; 4 rows created. ops$tkyte@ORA10GR1> insert into emp 2 select emp.*, '*' from scott.emp; 14 rows created. ops$tkyte@ORA10GR1> 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

374 CHAPTER 10 ■ DATABASE TABLES 8 from emp, dept 9 where emp.deptno = dept.deptno 10 ) 11 order by deptno 12 / DEPT_BLK EMP_BLK F DEPTNO ---------- ---------- - ---------- 4792 4788 * 10 4792 4788 * 10 4792 4791 * 10 4792 4788 * 20 4792 4788 * 20 4792 4792 20 4792 4792 20 4792 4791 * 20 4792 4788 * 30 4792 4792 30 4792 4792 30 4792 4792 30 4792 4792 30 4792 4788 * 30 14 rows selected. More than half of the EMP rows are not on the block with the DEPT row. Loading the data using the cluster key instead of the table key, we get the following: ops$tkyte@ORA10GR1> 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 procedure successfully completed. ops$tkyte@ORA10GR1> 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,

374<br />

CHAPTER 10 ■ DATABASE TABLES<br />

8 from emp, dept<br />

9 where emp.deptno = dept.deptno<br />

10 )<br />

11 order by deptno<br />

12 /<br />

DEPT_BLK EMP_BLK F DEPTNO<br />

---------- ---------- - ----------<br />

4792 4788 * 10<br />

4792 4788 * 10<br />

4792 4791 * 10<br />

4792 4788 * 20<br />

4792 4788 * 20<br />

4792 4792 20<br />

4792 4792 20<br />

4792 4791 * 20<br />

4792 4788 * 30<br />

4792 4792 30<br />

4792 4792 30<br />

4792 4792 30<br />

4792 4792 30<br />

4792 4788 * 30<br />

14 rows selected.<br />

More than half of the EMP rows are not on the block with the DEPT row. Loading the data<br />

using the cluster key instead of the table key, we get the following:<br />

ops$tkyte@ORA10GR1> begin<br />

2 for x in ( select * from scott.dept )<br />

3 loop<br />

4 insert into dept<br />

5 values ( x.deptno, x.dname, x.loc );<br />

6 insert into emp<br />

7 select emp.*, 'x'<br />

8 from scott.emp<br />

9 where deptno = x.deptno;<br />

10 end loop;<br />

11 end;<br />

12 /<br />

PL/SQL procedure successfully completed.<br />

ops$tkyte@ORA10GR1> select dept_blk, emp_blk,<br />

2 case when dept_blk emp_blk then '*' end flag,<br />

3 deptno<br />

4 from (<br />

5 select dbms_rowid.rowid_block_number(dept.rowid) dept_blk,<br />

6 dbms_rowid.rowid_block_number(emp.rowid) emp_blk,

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!