
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>