ACE Director Alum Daniel Morgan, founder of Morgan's Library, is scheduling
complimentary technical Workshops on Database Security for the first 30
Oracle Database customers located anywhere in North America, EMEA, LATAM, or
APAC that send an email to
asra_us@oracle.com. Request a Workshop for
your organization today.
Note: The word cluster in Oracle bears not relationship to its use in SQL Server and other RDBMS products.
Data Dictionary Objects
ALL_CLUSTERS
CDB_CLUSTER_HASH_EXPRESSIONS
OBJ$
ALL_CLU_COLUMNS
CDB_CLU_COLUMNS
TAB$
ALL_CLUSTER_HASH_EXPRESSIONS
DBA_ALL_TABLES
USER_CLUSTERS
ALL_ALL_TABLES
DBA_CLUSTERS
USER_CLU_COLUMNS
CLU$
DBA_CLUSTER_HASH_EXPRESSIONS
USER_CLUSTER_HASH_EXPRESSIONS
CDB_ALL_TABLES
DBA_CLU_COLUMNS
USER_ALL_TABLES
CDB_CLUSTERS
System Privileges
ALTER ANY CLUSTER
CREATE CLUSTER
DROP ANY CLUSTER
CREATE ANY CLUSTER
Clustering By Hash
Data is co-located within a single block based on a hash key and a hash function. The phrase "HASH INDEX" refers to these objects.
Clustering By Index
Data is co-located within a single block based on a common column index.
Cluster Size Calculation
Size of the primary key of the parent + ((size of the primary key of the children) * # of children) - ((size of the primary key of the parent) * # of children).
For example:
If the parent is the employee table where the primary key is ssn (VARCHAR2(9)) and the child is table is pay where the primary key is ssn (VARCHAR2(9)) and date of payment
(date datatype which is 7 bytes) ... on average if there are 300 children records then 9 + (300 * (9+7)) - (300 * 9) or 9 + (300 * 7) = 2,109.
DECLARE
pid shc_airplane.program_id%TYPE;
datemod NUMBER(10,5);
BEGIN
pid := 777;
FOR i IN 1..999
LOOP
SELECT DECODE(pid, 737, 747, 747, 757,
757, 767, 767, 777, 777, 737)
INTO pid
FROM dual;
SELECT ROUND((EXTRACT(SECOND FROM SYSTIMESTAMP) *
1000), -2) / 100
INTO datemod
FROM dual;
INSERT INTO shc_airplane
(program_id, line_id, delivery_dt, order_dt)
VALUES
(pid, i, SYSDATE+datemod, SYSDATE-datemod);
INSERT INTO reg_airplane
(program_id, line_id, delivery_dt, order_dt)
VALUES
(pid, i, SYSDATE+datemod, SYSDATE-datemod);
END LOOP;
COMMIT;
END;
/
SELECT program_id, COUNT(*)
FROM reg_airplane
GROUP BY program_id;
SELECT program_id, COUNT(*)
FROM shc_airplane
GROUP BY program_id;
EXPLAIN PLAN
SET statement_id = 'reg'
FOR SELECT prod_id
FROM sh.sales
WHERE prod_id = 12292
ORDER BY time_id;
EXPLAIN PLAN
SET statement_id = 'shc'
FOR SELECT prod_id
FROM shc_sales
WHERE prod_id = 12292
ORDER BY time_id;
set linesize 121
set pagesize 40
SELECT * FROM table(dbms_xplan.display('PLAN_TABLE','reg','ALL'));
SELECT * FROM table(dbms_xplan.display('PLAN_TABLE','shc','ALL'));
The Sorted Hash Cluster related bug (8438978) reported by Morgan has been fixed as of 11.2.0.3 as shown here
SQL> CREATE CLUSTER sorted_hc (
program_id NUMBER(3),
line_id NUMBER(10) SORT,
delivery_dt DATE SORT)
TABLESPACE uwdata
HASHKEYS 11
HASH IS program_id;
Cluster created.
SQL> select object_name, object_type from user_objects order by 2,1;
OBJECT_NAME OBJECT_TYPE
------------------------------ -------------------
SORTED_HC CLUSTER <== the sorted hash cluster
BIX_SERV_INST_LOCATION_CODE INDEX
BIX_SERV_INST_WS_ID INDEX
IX_PROGRAM_ID INDEX
PK_SERVERS INDEX
PK_SERV_INST INDEX
PK_ZIP_CODE INDEX
SYS_IQ0000072193$$ INDEX <== the hash cluster's index
AIRPLANES TABLE
POSTAL_CODE TABLE
SERVERS TABLE
SERV_INST TABLE
12 rows selected.
SQL> select table_name from user_indexes
2 where index_name = 'SYS_IQ0000072193$$';
SQL> drop index SYS_IQ0000072193$$; <== attempt to drop the cluster's index
*
ERROR at line 1:
ORA-43814: DROP INDEX is invalid for hash cluster index
Cluster Range Partition
This demo is based on a single cluster type but all cluster objects can be range partitioned.
CREATE CLUSTER
...
PARTITION BY RANGE (<column_list>)
(PARTITION <partition_name> <range_values_clause> <table_partition_description>);
CREATE CLUSTER uwclass.airplanes (
program_id VARCHAR2(3),
line_number NUMBER(10),
customer_id VARCHAR2(4),
order_date DATE,
deliv_date DATE)
HASHKEYS 11
HASH IS (deliv_date = order_date + 1)
SIZE 300
TABLESPACE uwdata
PARTITION BY RANGE (program_id) (
PARTITION pMin VALUES LESS THAN ('707'), -- invalid program_id
PARTITION p707 VALUES LESS THAN ('717'),
PARTITION p717 VALUES LESS THAN ('727'),
PARTITION p727 VALUES LESS THAN ('737'),
PARTITION p737 VALUES LESS THAN ('747'),
PARTITION p747 VALUES LESS THAN ('757'),
PARTITION p757 VALUES LESS THAN ('767'),
PARTITION p767 VALUES LESS THAN ('777'),
PARTITION p777 VALUES LESS THAN ('767'),
PARTITION p787 VALUES LESS THAN ('788'),
PARTITION pMax VALUES LESS THAN (MAXVALUE)); -- future program_id