
A Reminder : The AIOUG Sangam '11 Conference 09-10 December, Bengaluru (Bangalore)
I am an Oracle Database Specialist in Singapore.
Please note that this site uses cookies.
SQL> connect / as sysdba
Connected.
SQL>
SQL>
SQL> -- demo behaviour of ASSM with multiple sessions inserting concurrently
SQL> -- data gets "distributed" to reduce block-contention
SQL> -- but this affects the Clustering Factor !
SQL>
SQL>
SQL> drop tablespace ASSM_TBS including contents and datafiles;
Tablespace dropped.
SQL> create tablespace ASSM_TBS extent management local autoallocate segment space management auto;
Tablespace created.
SQL> drop tablespace MSSM_TBS including contents and datafiles;
Tablespace dropped.
SQL> create tablespace MSSM_TBS extent management local autoallocate segment space management manual;
Tablespace created.
SQL>
SQL>
SQL> -- grants required for stored procedures to access v$process, v$session, v$mystat
SQL> grant select on v_$process to hemant;
Grant succeeded.
SQL> grant select on v_$session to hemant;
Grant succeeded.
SQL> grant select on v_$mystat to hemant;
Grant succeeded.
SQL>
SQL>
SQL> -- Reconnect as HEMANT
SQL> connect hemant/hemant
Connected.
SQL>
SQL> -- setup the Invoices table and PK index and sequence
SQL> drop table ASSM_Table;
drop table ASSM_Table
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> create table ASSM_Table (
2 invoice_id number not null,
3 invoice_date date,
4 invoice_details varchar2(50),
5 inserting_pid number)
6 tablespace ASSM_TBS
7 /
Table created.
SQL> create unique index ASSM_Table_PK on ASSM_Table(invoice_id) tablespace ASSM_TBS;
Index created.
SQL> alter table ASSM_Table add constraint ASSM_Table_PK primary key (invoice_id);
Table altered.
SQL> drop sequence ASSM_invoice_Seq ;
Sequence dropped.
SQL> create sequence ASSM_invoice_Seq start with 1 increment by 1 nocache ;
Sequence created.
SQL>
SQL>
SQL> drop table MSSM_Table;
drop table MSSM_Table
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> create table MSSM_Table (
2 invoice_id number not null,
3 invoice_date date,
4 invoice_details varchar2(50),
5 inserting_pid number)
6 tablespace MSSM_TBS
7 /
Table created.
SQL> create unique index MSSM_Table_PK on MSSM_Table(invoice_id) tablespace MSSM_TBS;
Index created.
SQL> alter table MSSM_Table add constraint MSSM_Table_PK primary key (invoice_id);
Table altered.
SQL> drop sequence MSSM_invoice_Seq ;
Sequence dropped.
SQL> create sequence MSSM_invoice_Seq start with 1 increment by 1 nocache;
Sequence created.
SQL>
SQL>
SQL> -- create procedures that will simulate an application server
SQL> -- or ETL engine that inserts 500 rows
SQL> create or replace procedure populate_ASSM_Table
2 as
3 i number;
4 begin
5 for i in 1..501
6 loop
7 insert into ASSM_Table
8 select ASSM_invoice_seq.nextval, sysdate+rownum/10000, rpad('A',40,'X'), pid
9 from
10 v$process p, v$session s
11 where p.addr=s.paddr
12 and s.sid=(select sid from v$mystat where rownum=1)
13 ;
14 end loop;
15 commit;
16 end;
17 /
Procedure created.
SQL>
SQL> create or replace procedure populate_MSSM_Table
2 as
3 i number;
4 begin
5 for i in 1..501
6 loop
7 insert into MSSM_Table
8 select MSSM_invoice_seq.nextval, sysdate+rownum/10000, rpad('A',40,'X'), pid
9 from
10 v$process p, v$session s
11 where p.addr=s.paddr
12 and s.sid=(select sid from v$mystat where rownum=1)
13 ;
14 end loop;
15 commit;
16 end;
17 /
Procedure created.
SQL>
SQL>
SQL> REM now run the procedures from three separate sessions
SQL> pause .............. wait for the procedures to be executed
.............. wait for the procedures to be executed
SQL>
SQL>
SQL> -- gather statistics on the tables and indexes
SQL> exec dbms_Stats.gather_table_stats('','ASSM_TABLE',estimate_percent=>100,cascade=>TRUE);
PL/SQL procedure successfully completed.
SQL> exec dbms_Stats.gather_table_stats('','MSSM_TABLE',estimate_percent=>100,cascade=>TRUE);
PL/SQL procedure successfully completed.
SQL>
SQL>
SQL> -- view statistics on the tables and indexes
SQL> select table_name, num_rows, blocks
2 from user_tables
3 where table_name in ('ASSM_TABLE','MSSM_TABLE')
4 order by 1
5 /
TABLE_NAME NUM_ROWS BLOCKS
------------------------------ ---------- ----------
ASSM_TABLE 1503 13
MSSM_TABLE 1503 15
SQL>
SQL> select index_name, num_rows, blevel, leaf_blocks, clustering_factor
2 from user_indexes
3 where index_name in ('ASSM_TABLE_PK','MSSM_TABLE_PK')
4 order by 1
5 /
INDEX_NAME NUM_ROWS BLEVEL LEAF_BLOCKS CLUSTERING_FACTOR
------------------------------ ---------- ---------- ----------- -----------------
ASSM_TABLE_PK 1503 1 4 302
MSSM_TABLE_PK 1503 1 3 17
SQL>
SQL>
SQL> -- view the number of distinct blocks
SQL> select inserting_pid,count(distinct(dbms_rowid.rowid_block_number(rowid)))
2 from ASSM_TABLE
3 group by inserting_pid
4 order by 1
5 /
INSERTING_PID COUNT(DISTINCT(DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)))
------------- -----------------------------------------------------
23 6
29 7
30 5
SQL>
SQL> select inserting_pid,count(distinct(dbms_rowid.rowid_block_number(rowid)))
2 from MSSM_TABLE
3 group by inserting_pid
4 order by 1
5 /
INSERTING_PID COUNT(DISTINCT(DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)))
------------- -----------------------------------------------------
23 7
29 6
30 8
SQL>
SQL> select * from v$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production PL/SQL Release 11.2.0.1.0 - Production CORE 11.2.0.1.0 Production TNS for Linux: Version 11.2.0.1.0 - Production NLSRTL Version 11.2.0.1.0 - Production SQL> show parameter deferred; NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ deferred_segment_creation boolean TRUE SQL> SQL> drop materialized view int_salestable; drop materialized view int_salestable * ERROR at line 1: ORA-12003: materialized view "HEMANT"."INT_SALESTABLE" does not exist SQL> SQL> drop TABLE salestable; Table dropped. SQL> SQL> CREATE TABLE salestable 2 (s_saleid NUMBER, 3 s_saledate DATE, 4 s_custid NUMBER, 5 s_totalprice NUMBER) 6 logging 7 TABLESPACE users 8 PARTITION BY RANGE(s_saledate) 9 (PARTITION sal03q1 VALUES LESS THAN (TO_DATE('01-APR-2003', 'DD-MON-YYYY')), 10 PARTITION sal03q2 VALUES LESS THAN (TO_DATE('01-JUL-2003', 'DD-MON-YYYY')), 11 PARTITION sal03q3 VALUES LESS THAN (TO_DATE('01-OCT-2003', 'DD-MON-YYYY')), 12 PARTITION sal03q4 VALUES LESS THAN (TO_DATE('01-JAN-2004', 'DD-MON-YYYY'))); Table created. SQL> SQL> SQL> alter table salestable modify s_saleid number primary key; Table altered. SQL> CREATE INDEX sales_index ON salestable(s_saledate, s_saleid, s_custid) logging LOCAL; Index created. SQL> SQL> select partition_name, tablespace_name from user_tab_partitions 2 where table_name = 'SALESTABLE' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 USERS SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL> SQL> select partition_name, tablespace_name from user_ind_partitions 2 where index_name = 'SALES_INDEX' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 USERS SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL> SQL> SQL> drop TABLE int_salestable ; Table dropped. SQL> SQL> CREATE TABLE int_salestable 2 (s_saleid NUMBER, 3 s_saledate DATE, 4 s_custid NUMBER, 5 s_totalprice NUMBER) 6 logging 7 tablespace example; Table created. SQL> SQL> alter table int_salestable modify s_saleid number primary key; Table altered. SQL> SQL> CREATE INDEX int_sales_index ON int_salestable 2 (s_saledate, s_saleid, s_custid) 3 logging 4 TABLESPACE example; Index created. SQL> SQL> SQL> BEGIN 2 DBMS_REDEFINITION.CAN_REDEF_TABLE( 3 uname => 'HEMANT', 4 tname => 'SALESTABLE', 5 options_flag => DBMS_REDEFINITION.CONS_USE_ROWID, 6 part_name => 'SAL03Q1'); 7 END; 8 / PL/SQL procedure successfully completed. SQL> SQL> BEGIN 2 DBMS_REDEFINITION.START_REDEF_TABLE( 3 uname => 'HEMANT', 4 orig_table => 'SALESTABLE', 5 int_table => 'INT_SALESTABLE', 6 col_mapping => NULL, 7 options_flag => DBMS_REDEFINITION.CONS_USE_ROWID, 8 part_name => 'SAL03Q1'); 9 END; 10 / PL/SQL procedure successfully completed. SQL> SQL> SQL> BEGIN 2 DBMS_REDEFINITION.FINISH_REDEF_TABLE( 3 uname => 'HEMANT', 4 orig_table => 'SALESTABLE', 5 int_table => 'INT_SALESTABLE', 6 part_name => 'SAL03Q1'); 7 END; 8 / BEGIN * ERROR at line 1: ORA-42012: error occurred while completing the redefinition ORA-04020: deadlock detected while trying to lock object HEMANT.INT_SALESTABLE ORA-06512: at "SYS.DBMS_REDEFINITION", line 78 ORA-06512: at "SYS.DBMS_REDEFINITION", line 1680 ORA-06512: at line 2 SQL> SQL> SQL> select partition_name, tablespace_name from user_tab_partitions 2 where table_name = 'SALESTABLE' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 USERS SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL> SQL> select partition_name, tablespace_name from user_ind_partitions 2 where index_name = 'SALES_INDEX' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 USERS SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL>
SQL> select * from v$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production PL/SQL Release 11.2.0.1.0 - Production CORE 11.2.0.1.0 Production TNS for Linux: Version 11.2.0.1.0 - Production NLSRTL Version 11.2.0.1.0 - Production SQL> show parameter deferred; NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ deferred_segment_creation boolean TRUE SQL> SQL> drop materialized view int_salestable; Materialized view dropped. SQL> SQL> drop TABLE salestable; Table dropped. SQL> SQL> CREATE TABLE salestable 2 (s_saleid NUMBER, 3 s_saledate DATE, 4 s_custid NUMBER, 5 s_totalprice NUMBER) 6 logging 7 TABLESPACE users 8 PARTITION BY RANGE(s_saledate) 9 (PARTITION sal03q1 VALUES LESS THAN (TO_DATE('01-APR-2003', 'DD-MON-YYYY')), 10 PARTITION sal03q2 VALUES LESS THAN (TO_DATE('01-JUL-2003', 'DD-MON-YYYY')), 11 PARTITION sal03q3 VALUES LESS THAN (TO_DATE('01-OCT-2003', 'DD-MON-YYYY')), 12 PARTITION sal03q4 VALUES LESS THAN (TO_DATE('01-JAN-2004', 'DD-MON-YYYY'))); Table created. SQL> SQL> insert into salestable partition (sal03q1) values (101,to_date('01-JAN-2003','DD-MON-YYYY'),1,2000); 1 row created. SQL> commit; Commit complete. SQL> SQL> alter table salestable modify s_saleid number primary key; Table altered. SQL> CREATE INDEX sales_index ON salestable(s_saledate, s_saleid, s_custid) logging LOCAL; Index created. SQL> SQL> select partition_name, tablespace_name from user_tab_partitions 2 where table_name = 'SALESTABLE' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 USERS SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL> SQL> select partition_name, tablespace_name from user_ind_partitions 2 where index_name = 'SALES_INDEX' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 USERS SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL> SQL> SQL> drop TABLE int_salestable ; Table dropped. SQL> SQL> CREATE TABLE int_salestable 2 (s_saleid NUMBER, 3 s_saledate DATE, 4 s_custid NUMBER, 5 s_totalprice NUMBER) 6 logging 7 tablespace example; Table created. SQL> SQL> alter table int_salestable modify s_saleid number primary key; Table altered. SQL> SQL> CREATE INDEX int_sales_index ON int_salestable 2 (s_saledate, s_saleid, s_custid) 3 logging 4 TABLESPACE example; Index created. SQL> SQL> SQL> BEGIN 2 DBMS_REDEFINITION.CAN_REDEF_TABLE( 3 uname => 'HEMANT', 4 tname => 'SALESTABLE', 5 options_flag => DBMS_REDEFINITION.CONS_USE_ROWID, 6 part_name => 'SAL03Q1'); 7 END; 8 / PL/SQL procedure successfully completed. SQL> SQL> BEGIN 2 DBMS_REDEFINITION.START_REDEF_TABLE( 3 uname => 'HEMANT', 4 orig_table => 'SALESTABLE', 5 int_table => 'INT_SALESTABLE', 6 col_mapping => NULL, 7 options_flag => DBMS_REDEFINITION.CONS_USE_ROWID, 8 part_name => 'SAL03Q1'); 9 END; 10 / PL/SQL procedure successfully completed. SQL> SQL> SQL> BEGIN 2 DBMS_REDEFINITION.FINISH_REDEF_TABLE( 3 uname => 'HEMANT', 4 orig_table => 'SALESTABLE', 5 int_table => 'INT_SALESTABLE', 6 part_name => 'SAL03Q1'); 7 END; 8 / PL/SQL procedure successfully completed. SQL> SQL> SQL> select partition_name, tablespace_name from user_tab_partitions 2 where table_name = 'SALESTABLE' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 EXAMPLE SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL> SQL> select partition_name, tablespace_name from user_ind_partitions 2 where index_name = 'SALES_INDEX' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 EXAMPLE SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL>
SQL> select * from v$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production PL/SQL Release 11.2.0.1.0 - Production CORE 11.2.0.1.0 Production TNS for Linux: Version 11.2.0.1.0 - Production NLSRTL Version 11.2.0.1.0 - Production SQL> show parameter deferred; NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ deferred_segment_creation boolean TRUE SQL> alter session set deferred_segment_creation=FALSE; Session altered. SQL> SQL> drop materialized view int_salestable; drop materialized view int_salestable * ERROR at line 1: ORA-12003: materialized view "HEMANT"."INT_SALESTABLE" does not exist SQL> SQL> drop TABLE salestable; Table dropped. SQL> SQL> CREATE TABLE salestable 2 (s_saleid NUMBER, 3 s_saledate DATE, 4 s_custid NUMBER, 5 s_totalprice NUMBER) 6 logging 7 TABLESPACE users 8 PARTITION BY RANGE(s_saledate) 9 (PARTITION sal03q1 VALUES LESS THAN (TO_DATE('01-APR-2003', 'DD-MON-YYYY')), 10 PARTITION sal03q2 VALUES LESS THAN (TO_DATE('01-JUL-2003', 'DD-MON-YYYY')), 11 PARTITION sal03q3 VALUES LESS THAN (TO_DATE('01-OCT-2003', 'DD-MON-YYYY')), 12 PARTITION sal03q4 VALUES LESS THAN (TO_DATE('01-JAN-2004', 'DD-MON-YYYY'))); Table created. SQL> SQL> SQL> alter table salestable modify s_saleid number primary key; Table altered. SQL> CREATE INDEX sales_index ON salestable(s_saledate, s_saleid, s_custid) logging LOCAL; Index created. SQL> SQL> select partition_name, tablespace_name from user_tab_partitions 2 where table_name = 'SALESTABLE' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 USERS SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL> SQL> select partition_name, tablespace_name from user_ind_partitions 2 where index_name = 'SALES_INDEX' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 USERS SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL> SQL> SQL> drop TABLE int_salestable ; Table dropped. SQL> SQL> CREATE TABLE int_salestable 2 (s_saleid NUMBER, 3 s_saledate DATE, 4 s_custid NUMBER, 5 s_totalprice NUMBER) 6 logging 7 tablespace example; Table created. SQL> SQL> alter table int_salestable modify s_saleid number primary key; Table altered. SQL> SQL> CREATE INDEX int_sales_index ON int_salestable 2 (s_saledate, s_saleid, s_custid) 3 logging 4 TABLESPACE example; Index created. SQL> SQL> SQL> BEGIN 2 DBMS_REDEFINITION.CAN_REDEF_TABLE( 3 uname => 'HEMANT', 4 tname => 'SALESTABLE', 5 options_flag => DBMS_REDEFINITION.CONS_USE_ROWID, 6 part_name => 'SAL03Q1'); 7 END; 8 / PL/SQL procedure successfully completed. SQL> SQL> BEGIN 2 DBMS_REDEFINITION.START_REDEF_TABLE( 3 uname => 'HEMANT', 4 orig_table => 'SALESTABLE', 5 int_table => 'INT_SALESTABLE', 6 col_mapping => NULL, 7 options_flag => DBMS_REDEFINITION.CONS_USE_ROWID, 8 part_name => 'SAL03Q1'); 9 END; 10 / PL/SQL procedure successfully completed. SQL> SQL> SQL> BEGIN 2 DBMS_REDEFINITION.FINISH_REDEF_TABLE( 3 uname => 'HEMANT', 4 orig_table => 'SALESTABLE', 5 int_table => 'INT_SALESTABLE', 6 part_name => 'SAL03Q1'); 7 END; 8 / PL/SQL procedure successfully completed. SQL> SQL> SQL> select partition_name, tablespace_name from user_tab_partitions 2 where table_name = 'SALESTABLE' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 EXAMPLE SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL> SQL> select partition_name, tablespace_name from user_ind_partitions 2 where index_name = 'SALES_INDEX' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 EXAMPLE SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL>
SQL> select * from v$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production PL/SQL Release 11.2.0.1.0 - Production CORE 11.2.0.1.0 Production TNS for Linux: Version 11.2.0.1.0 - Production NLSRTL Version 11.2.0.1.0 - Production SQL> show parameter deferred; NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ deferred_segment_creation boolean TRUE SQL> SQL> drop materialized view int_salestable; Materialized view dropped. SQL> SQL> drop TABLE salestable; Table dropped. SQL> SQL> CREATE TABLE salestable 2 (s_saleid NUMBER, 3 s_saledate DATE, 4 s_custid NUMBER, 5 s_totalprice NUMBER) 6 logging 7 TABLESPACE users 8 PARTITION BY RANGE(s_saledate) 9 (PARTITION sal03q1 VALUES LESS THAN (TO_DATE('01-APR-2003', 'DD-MON-YYYY')), 10 PARTITION sal03q2 VALUES LESS THAN (TO_DATE('01-JUL-2003', 'DD-MON-YYYY')), 11 PARTITION sal03q3 VALUES LESS THAN (TO_DATE('01-OCT-2003', 'DD-MON-YYYY')), 12 PARTITION sal03q4 VALUES LESS THAN (TO_DATE('01-JAN-2004', 'DD-MON-YYYY'))); Table created. SQL> SQL> SQL> alter table salestable modify s_saleid number primary key; Table altered. SQL> CREATE INDEX sales_index ON salestable(s_saledate, s_saleid, s_custid) logging LOCAL; Index created. SQL> SQL> select partition_name, tablespace_name from user_tab_partitions 2 where table_name = 'SALESTABLE' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 USERS SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL> SQL> select partition_name, tablespace_name from user_ind_partitions 2 where index_name = 'SALES_INDEX' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 USERS SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL> SQL> SQL> drop TABLE int_salestable ; Table dropped. SQL> SQL> CREATE TABLE int_salestable 2 (s_saleid NUMBER, 3 s_saledate DATE, 4 s_custid NUMBER, 5 s_totalprice NUMBER) 6 logging 7 tablespace example; Table created. SQL> SQL> alter table int_salestable modify s_saleid number primary key; Table altered. SQL> SQL> CREATE INDEX int_sales_index ON int_salestable 2 (s_saledate, s_saleid, s_custid) 3 logging 4 TABLESPACE example; Index created. SQL> SQL> SQL> BEGIN 2 DBMS_REDEFINITION.CAN_REDEF_TABLE( 3 uname => 'HEMANT', 4 tname => 'SALESTABLE', 5 options_flag => DBMS_REDEFINITION.CONS_USE_PK, 6 part_name => 'SAL03Q1'); 7 END; 8 / PL/SQL procedure successfully completed. SQL> SQL> BEGIN 2 DBMS_REDEFINITION.START_REDEF_TABLE( 3 uname => 'HEMANT', 4 orig_table => 'SALESTABLE', 5 int_table => 'INT_SALESTABLE', 6 col_mapping => NULL, 7 options_flag => DBMS_REDEFINITION.CONS_USE_PK, 8 part_name => 'SAL03Q1'); 9 END; 10 / PL/SQL procedure successfully completed. SQL> SQL> SQL> BEGIN 2 DBMS_REDEFINITION.FINISH_REDEF_TABLE( 3 uname => 'HEMANT', 4 orig_table => 'SALESTABLE', 5 int_table => 'INT_SALESTABLE', 6 part_name => 'SAL03Q1'); 7 END; 8 / BEGIN * ERROR at line 1: ORA-42012: error occurred while completing the redefinition ORA-04020: deadlock detected while trying to lock object HEMANT.INT_SALESTABLE ORA-06512: at "SYS.DBMS_REDEFINITION", line 78 ORA-06512: at "SYS.DBMS_REDEFINITION", line 1680 ORA-06512: at line 2 SQL> SQL> SQL> select partition_name, tablespace_name from user_tab_partitions 2 where table_name = 'SALESTABLE' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 USERS SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL> SQL> select partition_name, tablespace_name from user_ind_partitions 2 where index_name = 'SALES_INDEX' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 USERS SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL>
SQL> select * from v$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production PL/SQL Release 11.2.0.1.0 - Production CORE 11.2.0.1.0 Production TNS for Linux: Version 11.2.0.1.0 - Production NLSRTL Version 11.2.0.1.0 - Production SQL> show parameter deferred; NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ deferred_segment_creation boolean TRUE SQL> alter session set deferred_segment_creation=FALSE; Session altered. SQL> SQL> drop materialized view int_salestable; Materialized view dropped. SQL> SQL> drop TABLE salestable; Table dropped. SQL> SQL> CREATE TABLE salestable 2 (s_saleid NUMBER, 3 s_saledate DATE, 4 s_custid NUMBER, 5 s_totalprice NUMBER) 6 logging 7 TABLESPACE users 8 PARTITION BY RANGE(s_saledate) 9 (PARTITION sal03q1 VALUES LESS THAN (TO_DATE('01-APR-2003', 'DD-MON-YYYY')), 10 PARTITION sal03q2 VALUES LESS THAN (TO_DATE('01-JUL-2003', 'DD-MON-YYYY')), 11 PARTITION sal03q3 VALUES LESS THAN (TO_DATE('01-OCT-2003', 'DD-MON-YYYY')), 12 PARTITION sal03q4 VALUES LESS THAN (TO_DATE('01-JAN-2004', 'DD-MON-YYYY'))); Table created. SQL> SQL> SQL> alter table salestable modify s_saleid number primary key; Table altered. SQL> CREATE INDEX sales_index ON salestable(s_saledate, s_saleid, s_custid) logging LOCAL; Index created. SQL> SQL> select partition_name, tablespace_name from user_tab_partitions 2 where table_name = 'SALESTABLE' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 USERS SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL> SQL> select partition_name, tablespace_name from user_ind_partitions 2 where index_name = 'SALES_INDEX' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 USERS SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL> SQL> SQL> drop TABLE int_salestable ; Table dropped. SQL> SQL> CREATE TABLE int_salestable 2 (s_saleid NUMBER, 3 s_saledate DATE, 4 s_custid NUMBER, 5 s_totalprice NUMBER) 6 logging 7 tablespace example; Table created. SQL> SQL> alter table int_salestable modify s_saleid number primary key; Table altered. SQL> SQL> CREATE INDEX int_sales_index ON int_salestable 2 (s_saledate, s_saleid, s_custid) 3 logging 4 TABLESPACE example; Index created. SQL> SQL> SQL> BEGIN 2 DBMS_REDEFINITION.CAN_REDEF_TABLE( 3 uname => 'HEMANT', 4 tname => 'SALESTABLE', 5 options_flag => DBMS_REDEFINITION.CONS_USE_PK, 6 part_name => 'SAL03Q1'); 7 END; 8 / PL/SQL procedure successfully completed. SQL> SQL> BEGIN 2 DBMS_REDEFINITION.START_REDEF_TABLE( 3 uname => 'HEMANT', 4 orig_table => 'SALESTABLE', 5 int_table => 'INT_SALESTABLE', 6 col_mapping => NULL, 7 options_flag => DBMS_REDEFINITION.CONS_USE_PK, 8 part_name => 'SAL03Q1'); 9 END; 10 / PL/SQL procedure successfully completed. SQL> SQL> SQL> BEGIN 2 DBMS_REDEFINITION.FINISH_REDEF_TABLE( 3 uname => 'HEMANT', 4 orig_table => 'SALESTABLE', 5 int_table => 'INT_SALESTABLE', 6 part_name => 'SAL03Q1'); 7 END; 8 / PL/SQL procedure successfully completed. SQL> SQL> SQL> select partition_name, tablespace_name from user_tab_partitions 2 where table_name = 'SALESTABLE' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 EXAMPLE SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL> SQL> select partition_name, tablespace_name from user_ind_partitions 2 where index_name = 'SALES_INDEX' order by partition_name 3 / PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ SAL03Q1 EXAMPLE SAL03Q2 USERS SAL03Q3 USERS SAL03Q4 USERS SQL>
SQL>
SQL> -- demo behaviour of ASSM with multiple sessions inserting concurrently
SQL> -- data gets "distributed" to reduce block-contention
SQL> -- but this affects the Clustering Factor !
SQL>
SQL>
SQL> drop tablespace ASSM_TBS including contents and datafiles;
drop tablespace ASSM_TBS including contents and datafiles
*
ERROR at line 1:
ORA-00959: tablespace 'ASSM_TBS' does not exist
SQL> create tablespace ASSM_TBS extent management local autoallocate segment space management auto;
Tablespace created.
SQL> drop tablespace MSSM_TBS including contents and datafiles;
drop tablespace MSSM_TBS including contents and datafiles
*
ERROR at line 1:
ORA-00959: tablespace 'MSSM_TBS' does not exist
SQL> create tablespace MSSM_TBS extent management local autoallocate segment space management manual;
Tablespace created.
SQL>
SQL>
SQL> -- grants required for stored procedures to access v$process, v$session, v$mystat
SQL> grant select on v_$process to hemant;
Grant succeeded.
SQL> grant select on v_$session to hemant;
Grant succeeded.
SQL> grant select on v_$mystat to hemant;
Grant succeeded.
SQL>
SQL>
SQL> -- Reconnect as HEMANT
SQL> connect hemant/hemant
Connected.
SQL>
SQL> -- setup the Invoices table and PK index and sequence
SQL> drop table ASSM_Table;
drop table ASSM_Table
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> create table ASSM_Table (
2 invoice_id number not null,
3 invoice_date date,
4 invoice_details varchar2(50),
5 inserting_pid number)
6 tablespace ASSM_TBS
7 /
Table created.
SQL> create unique index ASSM_Table_PK on ASSM_Table(invoice_id) tablespace ASSM_TBS;
Index created.
SQL> alter table ASSM_Table add constraint ASSM_Table_PK primary key (invoice_id);
Table altered.
SQL> drop sequence ASSM_invoice_Seq ;
drop sequence ASSM_invoice_Seq
*
ERROR at line 1:
ORA-02289: sequence does not exist
SQL> create sequence ASSM_invoice_Seq start with 1 increment by 1;
Sequence created.
SQL>
SQL>
SQL> drop table MSSM_Table;
drop table MSSM_Table
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> create table MSSM_Table (
2 invoice_id number not null,
3 invoice_date date,
4 invoice_details varchar2(50),
5 inserting_pid number)
6 tablespace MSSM_TBS
7 /
Table created.
SQL> create unique index MSSM_Table_PK on MSSM_Table(invoice_id) tablespace MSSM_TBS;
Index created.
SQL> alter table MSSM_Table add constraint MSSM_Table_PK primary key (invoice_id);
Table altered.
SQL> drop sequence MSSM_invoice_Seq ;
drop sequence MSSM_invoice_Seq
*
ERROR at line 1:
ORA-02289: sequence does not exist
SQL> create sequence MSSM_invoice_Seq start with 1 increment by 1;
Sequence created.
SQL>
SQL>
SQL> -- create procedures that will simulate an application server
SQL> -- or ETL engine that inserts 50000 rows
SQL> create or replace procedure populate_ASSM_Table
2 as
3 i number;
4 begin
5 for i in 1..50001
6 loop
7 insert into ASSM_Table
8 select ASSM_invoice_seq.nextval, sysdate+rownum/10000, rpad('A',40,'X'), pid
9 from
10 v$process p, v$session s
11 where p.addr=s.paddr
12 and s.sid=(select sid from v$mystat where rownum=1)
13 ;
14 end loop;
15 commit;
16 end;
17 /
Procedure created.
SQL>
SQL> create or replace procedure populate_MSSM_Table
2 as
3 i number;
4 begin
5 for i in 1..50001
6 loop
7 insert into MSSM_Table
8 select MSSM_invoice_seq.nextval, sysdate+rownum/10000, rpad('A',40,'X'), pid
9 from
10 v$process p, v$session s
11 where p.addr=s.paddr
12 and s.sid=(select sid from v$mystat where rownum=1)
13 ;
14 end loop;
15 commit;
16 end;
17 /
Procedure created.
SQL>
SQL>
SQL> REM now run the procedures from three separate sessions
SQL> pause .............. wait for the procedures to be executed
.............. wait for the procedures to be executed
SQL>
SQL> -- gather statistics on the tables and indexes
SQL> exec dbms_Stats.gather_table_stats('','ASSM_TABLE',estimate_percent=>100,cascade=>TRUE);
PL/SQL procedure successfully completed.
SQL> exec dbms_Stats.gather_table_stats('','MSSM_TABLE',estimate_percent=>100,cascade=>TRUE);
PL/SQL procedure successfully completed.
SQL>
SQL>
SQL> -- view statistics on the tables and indexes
SQL> select table_name, num_rows, blocks
2 from user_tables
3 where table_name in ('ASSM_TABLE','MSSM_TABLE')
4 order by 1
5 /
TABLE_NAME NUM_ROWS BLOCKS
------------------------------ ---------- ----------
ASSM_TABLE 150003 1378
MSSM_TABLE 150003 1294
SQL>
SQL> select index_name, num_rows, blevel, leaf_blocks, clustering_factor
2 from user_indexes
3 where index_name in ('ASSM_TABLE_PK','MSSM_TABLE_PK')
4 order by 1
5 /
INDEX_NAME NUM_ROWS BLEVEL LEAF_BLOCKS CLUSTERING_FACTOR
------------------------------ ---------- ---------- ----------- -----------------
ASSM_TABLE_PK 150003 1 341 5729
MSSM_TABLE_PK 150003 1 334 1588
SQL>
SQL> -- view the number of distinct blocks
SQL> select inserting_pid,count(distinct(dbms_rowid.rowid_block_number(rowid)))
2 from ASSM_TABLE
3 group by inserting_pid
4 order by 1
5 /
INSERTING_PID COUNT(DISTINCT(DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)))
------------- -----------------------------------------------------
28 622
29 711
30 666
SQL>
SQL> select inserting_pid,count(distinct(dbms_rowid.rowid_block_number(rowid)))
2 from MSSM_TABLE
3 group by inserting_pid
4 order by 1
5 /
INSERTING_PID COUNT(DISTINCT(DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)))
------------- -----------------------------------------------------
28 1269
29 1290
30 1273
SQL>