What’s new in Oracle10g that is of interest to a DBA?

Simplified Oracle10g installation Enhanced Enterprise Manager Introducing DataPump - The load/unload utility Automatic Database Diagnostic Monitor Automatic Shared Memory Management Automatic Optimizer Statistics Gathering Automatic Undo Tuning Automatic Workload Repository Automatic Storage Management Automatic Maintenance Tasks SQL Tuning Advisor SQL Access Advisor Undo Advisor Redo Logfile Size Advisor Bigfile Tablespaces New Flashback Features The SYSAUX Tablespace Direct Upgrade to 10g UNIX Style Regular Expressions in SQL HTML DB New (bunch of) Wait Events New Initialization Parameters

Rename Tablespace Flush buffer cache Temporary Tablespace Groups Default Permanent Tablespace Segment Shrink Skip Unusable Indexes Drop Database Server Alerts Transport tablespace across platforms

What’s new in Oracle9i that is of interest to a DBA?

******* Automatic undo management
What is automatic undo? Oracle manages undo space using the undo tablespace instead of rollback segments Oracle manages the size and number of undo segments Relieves DBA from creating and monitoring rollback segments New type of tablespace required – UNDO TABLESPACE New initialization parameters UNDO_MANAGEMENT - Decides the type of undo management. AUTO specifies automatic undo management MANUAL specifies pre-9i behavior where the DBA manages rollback segments. This is the default UNDO_TABLESPACE – Name of the undo tablespace, this is a dynamic parameter, so you can change the name of the undo tablespace. You may have multiple undo tablespaces on the database, only one can be active at any given time. If you do not specify this parameter, oracle uses the first available undo tablespace. UNDO_RETENTION - specifies (in seconds) the amount of committed undo information to retain in the database. The default is 900 seconds. Keep this value high to avoid “Snapshot too old” errors. This is also a dynamic parameter, which can be changed using ALTER SYSTEM. UNDO_SUPPRESS_ERRORS - Suppress errors while executing manual undo management mode operations. If your application has SET TRANSACTION USE ROLLBACK SEGMENT statement, setting this parameter value to TRUE will suppress the error while in automatic undo. How to create an undo tablespace? Specify while creating the 9i database: CREATE DATABASE … … DATAFILE … … UNDO TABLESPACE "UNDOTBS" DATAFILE '/oradata/MYDB/undotbs01.dbf' SIZE 100M CHARACTER SET … … … Create using the CREATE TABLESPACE syntax: CREATE UNDO TABLESPACE UNDOTBS DATAFILE '/oradata/MYDB/undotbs01.dbf' SIZE 100M You can specify only DATAFILE and EXTENT MANAGEMENT LOCAL clauses when creating the UNDO TABLESPACE.

I just upgraded my database to 9i, how do I enable automatic undo management? Create an undo tablespace Include the UNDO_ parameters in your pfile or spfile. If using spfile, make sure you specify SCOPE=SPFILE Remove the rollback_segments parameter, if present in the init file. This will prevent the rollback segments going online when the database is started. Shutdown the database – make sure NOT to do SHUTDOWN ABORT. Startup the database. Drop the rollback segments and the rollback tablespace, if empty.

******* Automatic Segment Space Management
Automatic Segment Space Management (ASSM) introduced in Oracle9i is an easier way of managing space in a segment using bitmaps. It eliminates the DBA from setting the parameters pctused, freelists, and freelist groups. ASSM can be specified only with the locally managed tablespaces (LMT). The CREATE TABLESPACE statement has a new clause SEGMENT SPACE MANAGEMENT. Oracle uses bitmaps to manage the free space. A bitmap, in this case, is a map that describes the status of each data block within a segment with respect to the amount of space in the block available for inserting rows. As more or less space becomes available in a data block, its new state is reflected in the bitmap. Bitmaps allow Oracle to manage free space more automatically. Here is an example:
CREATE TABLESPACE myts DATAFILE '/oradata/mysid/myts01.dbf' SIZE 100M EXTENT MANAGEMENT LOCAL UNIFORM SIZE 2M SEGMENT SPACE MANAGEMENT AUTO;

The storage parameters PCTUSED, FREELISTS and FREELIST GROUPS specified while creating a table are ignored by Oracle on a LMT ASSM tablespace. Oracle does not produce an error. One huge benefit of having ASSM is to reduce the “Buffer Busy Waits” you see on segments. Peter Sherman’s presentation at RMOUG is a good one.

******* Rename Column
Oracle databases Oracle9i Release 2 and higher now allow you to rename a column in the table. ALTER TABLE table_name RENAME COLUMN old_name TO new_name Use the RENAME COLUMN clause of ALTER TABLE to rename a column. The new column name must not be the same as any other column name in table. Function-based indexes and check constraints that depend on the renamed column remain valid. Dependent views, triggers, domain indexes, functions, procedures, and packages are marked INVALID. Oracle attempts to revalidate them when they are next accessed, but you may need to alter these objects with the new column name if revalidation fails. You cannot combine this clause with any of the other column_clauses in the same statement. You cannot rename a column that is used to define a join index. Instead you must drop the index, rename the column, and re-create the index

******* Rename Constraints
Oracle9i Release 2 lets you rename the constraint names. Here is a demonstration: SQL> create table b_test (col1 number, col2 number, 2* constraint pk_b_test primary key (col1)) SQL> / Table created. SQL> select constraint_name from dba_constraints 2 where table_name = 'B_TEST'; CONSTRAINT_NAME -----------------------------PK_B_TEST 1 row selected. SQL> select index_name from dba_indexes

2

where table_name = 'B_TEST';

INDEX_NAME -----------------------------PK_B_TEST 1 row selected. SQL> alter index PK_B_TEST rename to B_TEST_PK; Index altered. SQL> select constraint_name from dba_constraints 2 where table_name = 'B_TEST'; CONSTRAINT_NAME -----------------------------PK_B_TEST 1 row selected. SQL> alter table b_test rename constraint PK_B_TEST to B_TEST_PK; Table altered. SQL> select constraint_name from dba_constraints 2 where table_name = 'B_TEST'; CONSTRAINT_NAME -----------------------------B_TEST_PK 1 row selected. SQL> What if you try to do the same in an Oracle8i database? SQL> create table b_test (col1 number, col2 number, 2 constraint pk_b_test primary key (col1)) 3 / Table created. SQL> select constraint_name from dba_constraints 2 where table_name = 'B_TEST';

CONSTRAINT_NAME -----------------------------PK_B_TEST 1 row selected. SQL> select index_name from dba_indexes 2 where table_name = 'B_TEST'; INDEX_NAME -----------------------------PK_B_TEST 1 row selected. SQL> alter index PK_B_TEST rename to B_TEST_PK; Index altered. SQL> select constraint_name from dba_constraints 2 where table_name = 'B_TEST'; CONSTRAINT_NAME -----------------------------PK_B_TEST 1 row selected. SQL> alter table b_test rename constraint PK_B_TEST to B_TEST_PK; alter table b_test rename constraint PK_B_TEST to B_TEST_PK * ERROR at line 1: ORA-14155: missing PARTITION or SUBPARTITION keyword

************

Data Compression

Block level compression is a new feature in Oracle9i Release 2, which is very useful in many data warehouses and read only large tables. Table compression can reduce storage space requirement (drastically some times) and may make the queries run faster (need to read only fewer blocks of data).

You may enable compression on a table at the time of table creation or by altering the table. Remember the existing data in the table is not compressed on uncompressed when you do the “alter”. CREATE TABLE MYTABLE ( COL1 VARCHAR2 (20), COL2 DATE) TABLESPACE MYTABLESPACE NOLOGGING COMPRESS PCTFREE 0; ALTER TABLE MYTABLE COMPRESS; The data compression is transparent to the user. You run queries against the table the same way you use to do before. Oracle compresses data blocks only when the data is loaded in direct path. The statements could be INSERT with APPEND hint INSERT with PARALLEL hint (parallel DML) CREATE TABLE AS SQL*Loader DIRECT LOAD Rows loaded using conventional insert statements are not compressed. Compression is suitable for large tables, where the updates/deletes are close to none. If there are updates/deletes, you may end up using more space – to update, Oracle has to uncompress the row, and insert it again; row deleted will free up some space which may not be sufficient for the next inserted row, because conventional inserts are not compressed, direct load inserts always load above the HWM. You can either compress the table, or selectively on partitions. It may be a good idea to compress the older data on a partitioned table. To do this, you have to perform a ALTER TABLE MYPARTTABLE MOVE PARTITION JAN04 TABLESPACE COMP_DATA COMPRESS PCTFREE 0; After the partition move, you may also have to do: ALTER TABLE MYPARTTABLE MODIFY PARTITION JAN04 REBUILD UNUSABLE LOCAL INDEXES; Another place to use compression is when you create materialized views, because most of the MVs are read only. If the MV already exist, you may do ALTER MATERIALIZED VIEW MYMV COMPRESS;

The data will be compressed when the materialized view is refreshed. Restrictions: You cannot specify data segment compression for an indexorganized table, for any overflow segment or partition of an overflow segment, or for any mapping table segment of an index-organized table. You cannot specify data segment compression for hash partitions or for either hash or list sub-partitions. You cannot specify data segment compression for an external table. The dictionary views DBA_TABLES, DBA_TAB_PARTITIONS have a column named COMPRESSION, which will be either DISABLED or ENABLED.

******** Index Key Compression
Index key compression introduced in Oracle9i lets you compress the leading columns of an index (or index organized table) to save space. Oracle compresses only nonpartitioned indexes that are non-unique or unique indexes of at least two columns. Bitmap indexes cannot be compressed. Generally, keys in an index have two pieces, a grouping piece and a unique piece. If the key is not defined to have a unique piece, Oracle provides one in the form of a rowid appended to the grouping piece. Key compression is a method of breaking off the grouping piece and storing it so it can be shared by multiple unique pieces. Key compression is achieved by breaking the index entry into two pieces – a prefix entry (or the grouping piece) and the suffix entry (the unique piece). Key compression is done within an index block but not across multiple index blocks. Suffix entries form the compressed version of index rows. Each suffix entry references a prefix entry, which is stored in the same index block as the suffix entry. Although key compression reduces the storage requirements of an index, it can increase the CPU time required to reconstruct the key column values during an index scan. It also incurs some additional storage overhead, because every prefix entry has an overhead of 4 bytes associated with it. Example creating a compressed index-organized table: CREATE TABLE BIJU_TEST_C (OWNER VARCHAR2(30), TABLE_NAME VARCHAR2(30),

TABLESPACE_NAME VARCHAR2 (30), PRIMARY KEY (OWNER, TABLE_NAME)) ORGANIZATION INDEX COMPRESS; Example creating a compressed index: CREATE INDEX BIJU_IND1 ON BIJU_TAB1 (COUNTRY, STATE, SEX) TABLESPACE INDX_TS COMPRESS; You can specify an integer along with the COMPRESS clause, which specifies the number of prefix columns to compress. For unique indexes, the valid range of prefix length values is from 1 to the number of key columns minus 1. The default is the number of key columns minus 1. For non-unique indexes, the valid range is from 1 to the number of key columns. The default is the number of key columns.

******** Flashback Query
Flashback query is a new feature in Oracle9i to recover from human errors. It allows users to view the state of data at a point in time in the past without requiring any structural changes to the database. Using Flashback Query, you can execute queries against a snapshot of data consistent to a point in time in the past either by specifying a system clock time or a System Change Number (SCN). Since flashback query is done using the “AS OF” clause of the SELECT statement, the developers/users do not need any administrative privileges or DBA intervention. While you query the old data, the table with current data is available for other users. The flashback clause of the SELECT statement has the following syntax:
AS OF {SCN | TIMESTAMP} expr

Let’s demonstrate the flashback-query using example. Notice that the COMMIT is what completes a transaction. 11:16:47 SQL> select object_name, object_type 11:16:57 2 from test 11:17:01 3 where owner = 'OUTLN'; OBJECT_NAME ------------------------OL$ OL$HINTS OBJECT_TYPE -----------------TABLE TABLE

OL$HNT_NUM OL$NAME OL$NODES OL$SIGNATURE ORA$GRANT_SYS_SELECT 7 rows selected.

INDEX INDEX TABLE INDEX PROCEDURE

11:17:08 SQL> 11:17:14 SQL> update test 11:17:22 2 set object_type = 'INVALID' 11:17:53 3 where object_name = 'ORA$GRANT_SYS_SELECT'; 1 row updated. 12:32:12 SQL> delete from test 12:32:18 2 where object_name = 'OL$NODES'; 1 row deleted. 12:32:51 SQL> update test 12:32:58 2 set object_type = 'VALID' 12:33:07 3 where object_name = 'ORA$GRANT_SYS_SELECT'; 1 row updated. 12:33:20 SQL>commit; Commit complete. 12:33:23 SQL> 12:37:56 SQL> 12:37:57 SQL> select object_name, object_type 12:38:03 2 from test 12:38:03 3 where owner = 'OUTLN'; OBJECT_NAME ------------------------OL$ OL$HINTS OL$HNT_NUM OL$NAME OL$SIGNATURE ORA$GRANT_SYS_SELECT 6 rows selected. OBJECT_TYPE -----------------TABLE TABLE INDEX INDEX INDEX VALID

12:38:04 SQL> 12:40:53 SQL> select object_name, object_type 12:41:02 2 from test AS OF TIMESTAMP TO_TIMESTAMP('20040226123251','YYYYMMDDHHMISS') 12:42:39 3 where owner = 'OUTLN'; OBJECT_NAME ------------------------OL$ OL$HINTS OL$HNT_NUM OL$NAME OL$NODES OL$SIGNATURE ORA$GRANT_SYS_SELECT 7 rows selected. 12:42:44 SQL> 12:43:15 SQL> select object_name, object_type 2 from test AS OF TIMESTAMP TO_TIMESTAMP('20040226123319','YYYYMMDDHHMISS') 3 where owner = 'OUTLN' 12:43:51 SQL>/ OBJECT_NAME ------------------------OL$ OL$HINTS OL$HNT_NUM OL$NAME OL$NODES OL$SIGNATURE ORA$GRANT_SYS_SELECT 7 rows selected. 12:43:51 SQL> By writing proper sub queries and update statements you can recover the rows. OBJECT_TYPE -----------------TABLE TABLE INDEX INDEX TABLE INDEX PROCEDURE OBJECT_TYPE -----------------TABLE TABLE INDEX INDEX TABLE INDEX PROCEDURE

******** Object Privileges by DBA
Finally Oracle realized that DBA should have the privilege to grant object privileges. From Oracle9i Release 2 onwards, you need not login as the owner of the object to grant

an object privilege. In the earlier releases since most of the time I do not remember the schema password, had to login as the schema using the "back door"! A new system privilege, "GRANT ANY OBJECT PRIVILEGE" is introduced to control the delegation of an owner's right to grant and revoke object privileges. In pre-Oracle9iR2 databases, to grant an object privilege on an object that belonged to another user, you should have granted the privilege with the GRANT option. GRANT ANY PRIVILEGE still gives the grantee privilege to grant any system privilege.

******** Default Temporary Tablespace
Oracle9i introduced a new clause in the CREATE DATABASE and ALTER DATABASE statements to assign a default temporary tablespace for the database. When creating users, if you do not provide the TEMPORARY TABLESPACE clause, Oracle uses this tablespace as the users temporary tablespace. (The default for DEFAULT TABLESPACE for the user is still SYSTEM J). When you ALTER the DEFAULT TEMPORARY TABLESPACE for the database, Oracle reassigns the temporary tablespace of the users with the default assignment to the new tablespace. Here is an example:
SQL> select property_value from database_properties 2 where PROPERTY_NAME = 'DEFAULT_TEMP_TABLESPACE'; PROPERTY_VALUE ----------------------------------SYSTEM 1 row selected. SQL> create user test_biju identified by test; User created. SQL> select default_tablespace, temporary_tablespace 2 from dba_users where username = 'TEST_BIJU'; DEFAULT_TABLESPACE TEMPORARY_TABLESPACE ------------------------------ -----------------------------SYSTEM SYSTEM 1 row selected. SQL> alter database default temporary tablespace temp; Database altered.

SQL> select default_tablespace, temporary_tablespace 2 from dba_users where username = 'TEST_BIJU'; DEFAULT_TABLESPACE TEMPORARY_TABLESPACE ------------------------------ -----------------------------SYSTEM TEMP 1 row selected. SQL>

A default temporary tablespace cannot be taken offline until a new default temporary tablespace is online Here is something interesting from the Oracle documentation: If you specify the EXTENT MANAGEMENT LOCAL clause for the SYSTEM tablespace when creating a database, the database must have a default temporary tablespace, because a locally managed SYSTEM tablespace cannot store temporary segments. If you specify EXTENT MANAGEMENT LOCAL but you do not specify the DATAFILE clause, you can omit the default_temp_tablespace clause. Oracle will create a default temporary tablespace called TEMP with one datafile of size 10M with autoextend disabled. If you specify both EXTENT MANAGEMENT LOCAL and the DATAFILE clause, then you must also specify the default_temp_tablespace clause and explicitly specify a datafile for that tablespace.

******** Resumable Space Allocation
Do you often have issues with batch jobs running out of space producing unable to extent errors in the database? Now Oracle can suspend the session in error until you add more space and resume the session from where it left…. Resumable space allocation solution can be used for the following errors: • • • • • ORA-1650 tablespace ORA-1653 ORA-1654 ORA-1628 ORA-1631 unable ... unable unable max # max # to extend rollback segment ... in to extend table ... in tablespace ... to extend index ... in tablespace ... extents ... reached for rollback segment ... extents ... reached in table ...


ORA-1654 max # extents ... reached in index ... ORA-1536 space quote exceeded for tablespace string

The session need to enable the resumable mode using: ALTER SESSION ENABLE RESUMABLE; The following views can be queried to obtain information about the status of resumable statements: View
DBA_RESUMABLE

Description

These views contain rows for all currently executing or suspended resumable statements. They can be used by a DBA, AFTER SUSPEND USER_RESUMABLE trigger, or another session to monitor the progress of, or obtain specific information about, resumable statements.
V$SESSION_WAIT

When a statement is suspended the session invoking the statement is put into a wait state. A row is inserted into this view for the session with the EVENT column containing "statement suspended, wait error to be cleared".

To read more: OTN – 9i Daily Feature – November 26 Oracle Documentation – Administrators Guide – Chapter 14

******** List Partitioning
Oracle9i introduces another type of partitioning in addition to the RANGE and HASH partitions of 8i. List partitioning lets you create partitions based on a list of values. For example, if you have a sales table, and you want to partition the table by the region, you might create the table as: create table list_example ( state char(2), amount number) partition by list (state) ( partition south values ('TX','LA','OK'), partition north values ('NY','DE','MA'), partition others values (DEFAULT) ) /

If you omit the partition name, then Oracle assigns partition names of the form SYS_Pn. The DEFAULT keyword, introduced in Oracle9i release 2, creates a partition into which Oracle will insert any row that does not map to another partition. Therefore, you can specify DEFAULT for only one partition, and you cannot specify any other values for that partition. Further, the default partition must be the last partition you define (similar to the use of MAXVALUE for range partitions). The index-organized table cannot be list-partitioned.

******** Range-list Partitioning
Prior to Oracle9i, the only sub-partitioning method available was to partition the table by range, and sub-partition by hash. Oracle9i release 2 allows you to partition the table by range and then sub-partition by list. These are the only sub-partitioning methods in Oracle9i. The following are the versions and partitioning methods available, just to refresh your memory: <![endif]> Oracle8 Range Oracle8i Range Hash Range-Hash Range-Hash Range-Hash Range-List Oracle9iR1 Range Hash List Oracle9iR2 Range Hash List

Here is an example of creating a range-list partitioned table: create table range_list_example ( sales_dt date, state char(2), amount number) partition by range (sales_dt) subpartition by list (state) ( partition s2004q1 values less than (to_date('04-2004','MM-YYYY')) (subpartition s2004q1_south values ('TX','LA','OK'), subpartition s2004q1_north values ('NY','DE','MA'), subpartition s2004q1_others values (DEFAULT)), partition s2004q2

values less than (to_date('07-2004','MM-YYYY')) (subpartition s2004q2_south values ('TX','LA','OK'), subpartition s2004q2_north values ('NY','DE','MA'), subpartition s2004q2_others values (DEFAULT)) ) / The same sub-partitions can be created using a sub-partition template as in the following example: create table range_list_example ( sales_dt date, state char(2), amount number) partition by range (sales_dt) subpartition by list (state) subpartition template (subpartition south values ('TX','LA','OK'), subpartition north values ('NY','DE','MA'), subpartition others values (DEFAULT)) ( partition s2004q1 values less than (to_date('04-2004','MM-YYYY')), partition s2004q2 values less than (to_date('07-2004','MM-YYYY')) ) /

******** External Tables
External Table introduced in Oracle9i is and excellent feature for ETL operations, allows for flat files that reside outside the database, to be accessed just like relational tables within the database. The flat-file data can be queried and joined to other tables using standard SQL. From a user’s point of view, the main difference between an external table and a regular table is that the external table is read-only. The metadata is stored in the Oracle database, where as the actual data resides outside the database. You create the external table using the ORAGANIZATION EXTERNAL clause of the CREATE TABLE. To create an external table, you must create a DIRECTORY in Oracle and have the READ object privilege on the directory in which the external data resides. Also, no constraints are permitted on external tables. CREATE DIRECTORY "UNIX_FLATFILE" AS '/FileImport/Externall';

GRANT READ ON DIRECTORY "UNIX_FLATFILE" TO "MYUSER";
CREATE TABLE MYUSER.TEST_EXT_TAB ( ASS_ID NUMBER, TID_ID NUMBER, ASS_DATE VARCHAR2(10 BYTE), MCFD VARCHAR2(5 BYTE), HRS VARCHAR2(5 BYTE), PRES VARCHAR2(6 BYTE), PIPELINE VARCHAR2(30 BYTE), DAILY_DATE VARCHAR2(18 BYTE) ) ORGANIZATION EXTERNAL ( TYPE ORACLE_LOADER DEFAULT DIRECTORY UNIX_FLATFILE ACCESS PARAMETERS ( RECORDS DELIMITED BY NEWLINE CHARACTERSET WE8MSWIN1252 STRING SIZES ARE IN BYTES BADFILE ‘mydata.bad’ NODISCARDFILE NOLOGFILE SKIP 1 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' AND '"' NOTRIM ) LOCATION (UNIX_FLATFILE:'mydata.csv') ) REJECT LIMIT UNLIMITED;

External tables can be used to load data to a database, where you have to do some data manipulation. This avoids couple of steps in the conventional method, where you would load the data to a temporary table and then load the destination tables using queries. Oracle9i's external tables are a complement to the existing SQL*Loader functionality, and are especially useful for environments where the complete external source has to be joined with existing database objects and transformed in a complex manner, or where the external data volume is large and used only once. SQL*Loader, on the other hand, might still be the better choice for loading of data where additional indexing of the staging table is necessary. This is true for operations where the data is used in independent complex transformations or the data is only partially used in further processing. Dictionary Views that show external table information: SQL >desc dba_external_tables Name ------------------------------OWNER TABLE_NAME TYPE_OWNER Null? -------NOT NULL NOT NULL Type -----------VARCHAR2(30) VARCHAR2(30) CHAR(3)

TYPE_NAME DEFAULT_DIRECTORY_OWNER DEFAULT_DIRECTORY_NAME REJECT_LIMIT ACCESS_TYPE ACCESS_PARAMETERS SQL > SQL >desc dba_external_locations Name ------------------------------OWNER TABLE_NAME LOCATION DIRECTORY_OWNER DIRECTORY_NAME SQL >

NOT NULL VARCHAR2(30) CHAR(3) NOT NULL VARCHAR2(30) VARCHAR2(40) VARCHAR2(7) VARCHAR2(4000)

Null? -------NOT NULL NOT NULL

Type ---------------VARCHAR2(30) VARCHAR2(30) VARCHAR2(4000) CHAR(3) VARCHAR2(30)

******** Tuning Advisories
To help DBA tune the database, Oracle9i Release 2 introduces the following tuning advisories: Dynamic Buffer Cache Advisory MTTR Advisory Shared Pool Advisory PGA Target Advisory The advisories are turned on based on the value of initialization parameter STATISTICS_LEVEL. It could have values BASIC, TYPICAL or ALL. The parameter is dynamic – can be changed using ALTER SYSTEM or ALTER SESSION. The default value is TYPICAL. BASIC does not collect any statistics or advisories. Dictionary view V$STATISTICS_LEVEL gives the various statistics collection and advisories turned on in the database and their explanation. Here is one from a database:
Statistics name Buffer Cache Advice MTTR Advice PGA Advice Plan Execution Statistics Segment Level Statistics

Description Predicts the impact of different cache sizes on number of physical reads Predicts the impact of different MTTR settings on number of physical I/Os Predicts the impact of different values of pga_aggregate_target on the performance of memory operators Enables collection of plan execution statistics Enables gathering of segment access statistics

Shared Pool Advice Timed OS Statistics Timed Statistics

Predicts the impact of different values of shared_pool_size on elapsed parse time saved Enables gathering of timed operating system statistics Enables gathering of timed statistics

The above table pretty much explains what you get with the advisories and which views to look for results.

******** Dynamic Sampling of Optimizer Statistics
Dynamic sampling introduced in Oracle9i Release 2 improves server performance by determining more accurate selectivity and cardinality estimates for queries. You can use dynamic sampling to: Estimate single-table predicate selectivities when collected statistics cannot be used or are likely to lead to significant errors in estimation. Estimate table cardinality for tables without statistics or for tables whose statistics are too out of date to trust. Dynamic sampling is controlled by the initialization parameter

OPTIMIZER_DYNAMIC_SAMPLING. It could have a value between 0 and 10.

A value of 0 means dynamic sampling will not be done. A value of 1 (the

default) means dynamic sampling will be performed if all of the following conditions are true: There is more than one table in the query. Some table has not been analyzed and has no indexes. The optimizer determines that a relatively expensive table scan would be required for this unanalyzed table. Increasing the value of the parameter results in more aggressive application of dynamic sampling, in terms of both the type of tables sampled (analyzed or unanalyzed) and the amount of I/O spent on sampling.

******** Dynamic Database Parameters
Oracle9i includes several database initialization parameters that can be changed dynamically using ALTER SYSTEM or ALTER SESSION. The following are the parameters that were not modifiable in 8i, which can be modified in 9i using ALTER SYSTEM. SHARED_POOL_SIZE LARGE_POOL_SIZE LOG_CHECKPOINTS_TO_ALERT SERVICE_NAMES LOCAL_LISTENER OPEN_CURSORS The following are the new parameters introduced in Oracle9i that are dynamic.
NAME archive_lag_target db_16k_cache_size db_2k_cache_size db_32k_cache_size DESCRIPTION Maximum number of seconds of redos the standby could lose Size of cache for 16K buffers Size of cache for 2K buffers Size of cache for 32K buffers

db_4k_cache_size Size of cache for 4K buffers db_8k_cache_size Size of cache for 8K buffers db_cache_advice Buffer cache sizing advisory db_cache_size Size of DEFAULT buffer pool for standard block size buffers db_create_file_dest default database location db_create_online_log_dest_1 online log/controlfile destination #1 db_create_online_log_dest_2 online log/controlfile destination #2 db_create_online_log_dest_3 online log/controlfile destination #3 db_create_online_log_dest_4 online log/controlfile destination #4 db_create_online_log_dest_5 online log/controlfile destination #5 db_keep_cache_size Size of KEEP buffer pool for standard block size buffers db_recycle_cache_size Size of RECYCLE buffer pool for standard block size buffers dg_broker_config_file1 data guard broker configuration file #1 dg_broker_config_file2 data guard broker configuration file #2 dg_broker_start start Data Guard broker framework (DMON process) dispatchers specifications of dispatchers drs_start start DG Broker monitor (DMON process) fal_client FAL client fal_server FAL server list fast_start_mttr_target MTTR target of forward crash recovery in seconds file_mapping enable file mapping filesystemio_options IO operations on filesystem files log_archive_dest_10 archival destination #10 text string log_archive_dest_6 archival destination #6 text string log_archive_dest_7 archival destination #7 text string log_archive_dest_8 archival destination #8 text string log_archive_dest_9 archival destination #9 text string log_archive_dest_state_10 archival destination #10 state text string log_archive_dest_state_6 archival destination #6 state text string log_archive_dest_state_7 archival destination #7 state text string log_archive_dest_state_8 archival destination #8 state text string log_archive_dest_state_9 archival destination #9 state text string nls_length_semantics create columns using byte or char semantics by default nls_nchar_conv_excp NLS raise an exception instead of allowing implicit conversion olap_page_pool_size size of the olap page pool in bytes optimizer_dynamic_sampling optimizer dynamic sampling pga_aggregate_target Target size for the aggregate PGA memory consumed by the instanc plsql_compiler_flags PL/SQL compiler flags plsql_native_c_compiler plsql native C compiler plsql_native_library_dir plsql native library dir plsql_native_library_subdir_count plsql native library number of subdirectories plsql_native_linker plsql native linker plsql_native_make_file_name plsql native compilation make file

plsql_native_make_utility remote_listener shared_servers standby_file_management statistics_level trace_enabled undo_retention undo_suppress_errors undo_tablespace workarea_size_policy

plsql native compilation make utility remote listener number of shared servers to start up if auto then files are created/dropped automatically on standby statistics level enable KST tracing undo retention in seconds Suppress RBU errors in SMU mode use/switch undo tablespace policy used to size SQL working areas (MANUAL/AUTO)

******** Dynamic Memory Management / Automatic Memory Tuning
Automatic PGA Memory Management
With Oracle 9i a new method of tuning the PGA memory areas was introduced. Automatic PGA Memory Management takes the place of setting the sort_area_size, sort_area_retained_size, sort_area_hash_size and other related memory management parameters that all Oracle DBA's are familiar with. The PGA memory management is now controlled by just two parameters
• •

pga_aggregate_target, workarea_size_policy

Note that work_area_size_policy can be altered per database session, allowing manual memory management on a per session basis if needed. eg. a session is loading a large import file and a rather large sort_area_size is needed. A logon trigger could be used to set the work_area_size policy for the account doing the import. A session is normally allowed to use up to approximately 5% of the PGA memory available. This is controlled by the undocumented initialization parameter _smm_max_size. This value is specified in kilobytes. eg. a value of 1000 really means 1000k. As with all undocumented parameters, don't expect help from Oracle support with it, as you are not supposed to use it. If you experiment with it, do so on a test system. Also note that Automate PGA management can only be used for dedicated server sessions. For more some good reading on Automatic PGA management, please see: Oracle Documentation for Tuning PGA

The documentation contains some good guidelines for initial settings, and how to monitor and tune them as needed. If your 9i database is currently using manual PGA management, there are views available to help you make a reasonable estimate for the setting. If your database also has statspack statistics, then there is also historical information available to help you determine the setting. An initial setting can be determined by simply monitoring the amount of PGA memory being used by the system as seen in v$pgastat, and by querying the v$pga_target_for_estimate view.

v$pgastat:
select * from v$pgastat order by lower(name) / NAME VALUE UNIT ---------------------------------------- ------------------ -----------aggregate PGA auto target 8,294,400.00 bytes aggregate PGA target parameter 25,165,824.00 bytes bytes processed 24,929,280.00 bytes cache hit percentage 86.31 percent extra bytes read/written 3,953,664.00 bytes global memory bound 1,257,472.00 bytes maximum PGA allocated 26,661,888.00 bytes maximum PGA used for auto workareas 172,032.00 bytes maximum PGA used for manual workareas 525,312.00 bytes over allocation count .00 PGA memory freed back to OS 6,750,208.00 bytes total freeable PGA memory 65,536.00 bytes total PGA allocated 23,957,504.00 bytes total PGA inuse 15,283,200.00 bytes total PGA used for auto workareas .00 bytes total PGA used for manual workareas .00 bytes 16 rows selected.

The statistic "maximum PGA allocated" will display the maximum amount of PGA memory allocated during the life of the instance. The statistic "maximum PGA used for auto workareas" and "maximum PGA used for manual workareas" will display the maximum amount of PGA memory used for each type of workarea during the life of the instance.

v$pga_target_advice:
select * from v$pga_target_advice

order by pga_target_for_estimate / PGA TARGET PGA TARGET ESTIMATED EXTRA ESTIMATED PGA ESTIMATED OVER FOR EST FACTOR ADV BYTES PROCESSED BYTES RW CACHE HIT % ALLOC COUNT ---------------- ---------- --- ---------------- ---------------------------- -------------12,582,912 .50 ON 17,250,304 0 100.00 3 18,874,368 .75 ON 17,250,304 0 100.00 3 25,165,824 1.00 ON 17,250,304 0 100.00 0 30,198,784 1.20 ON 17,250,304 0 100.00 0 35,231,744 1.40 ON 17,250,304 0 100.00 0 40,264,704 1.60 ON 17,250,304 0 100.00 0 45,297,664 1.80 ON 17,250,304 0 100.00 0 50,331,648 2.00 ON 17,250,304 0 100.00 0 75,497,472 3.00 ON 17,250,304 0 100.00 0 100,663,296 4.00 ON 17,250,304 0 100.00 0 150,994,944 6.00 ON 17,250,304 0 100.00 0 201,326,592 8.00 ON 17,250,304 0 100.00 0 12 rows selected.

Querying v$pga_target_advice can help you determine a good setting for pga_aggregate_target. As seen in the previous query, an 18M PGA setting would have caused Oracle to allocate more memory than specified on 3 occasions. With a 25M PGA, this would not have happened. Keep in mind that pga_aggregate_target is not set in stone. It is used to help Oracle better manage PGA memory, but Oracle will exceed this setting if necessary. There are other views that are also useful for PGA memory management.

v$process:
select max(pga_used_mem) max_pga_used_mem , max(pga_alloc_mem) max_pga_alloc_mem , max(pga_max_mem) max_pga_max_mem from v$process /

This will show the maximum PGA usage per process:
select max(pga_used_mem) max_pga_used_mem , max(pga_alloc_mem) max_pga_alloc_mem , max(pga_max_mem) max_pga_max_mem from v$process /

This displays the sum of all current PGA usage per process:
select sum(pga_used_mem) sum_pga_used_mem , sum(pga_alloc_mem) sum_pga_alloc_mem , sum(pga_max_mem) sum_pga_max_mem from v$process /

Be sure to read the documentation referenced earlier, it contains an excellent explanation of Automatic PGA Memory Management. Following are some already canned scripts that may be of use.

******** Server Parameter File
Server parameter file (SPFILE) is new in Oracle9i that could be used to replace your initialization file. While creating a database, you need to start with the traditional text initialization parameter file (initSID.ora). SPFILE feature lets the DBA change the parameter values without directly login to the server. The SPFILE (spfile_SID.ora) is maintained on the server (on UNIX, $ORACLE_HOME/dbs directory) in a binary format by Oracle. You’re not supposed to edit this file. Changes to the SPFILE file are made using the ‘ALTER SYSTEM SET <parameter_name> = <value> SCOPE=SPFILE’ statement. The SCOPE=BOTH also changes the SPFILE. Examples:
ALTER SYSTEM SET USER_DUMP_DEST=’/ora_dump/SID’ SCOPE=SPFILE; ALTER SYSTEM SET SORT_AREA_SIZE=1048576 SCOPE=BOTH; ALTER SYSTEM SET ROLLBACK_SEGMENTS=’’ SCOPE=SPFILE;

SPFILE can be generated from the traditional initSID.ora file using the CREATE SPFILE FROM PFILE statement.

To change a parameter that need to open the database if the database is down, you need to do the following: 1. 2. 3. 4. STARTUP NOMOUNT ALTER SYSTEM SET … SCOPE=SPFILE; SHUTDOWN STARTUP

Read, “Managing initialization parameters using a server parameter file” from Oracle documentation.

******** Oracle Managed Files
Oracle Managed Files (OMF) is introduced in Oracle9i. OMF lets the DBA not worry about file names and location once a parameter is defined in the database. This is good for non-production databases where you can afford to keep all your data files in one location or on LVM systems. OMF is managed by the following parameters: DB_CREATE_FILE_DEST – Specifies the location of the data files. This parameter can be altered dynamically. DB_CREATE_ONLINE_LOG_DEST_n – Specifies the location of the redo log files. The ‘n’ can from 1 through 5, meaning you can specify up to 5 locations for redo log files. Advantages: No need to specify the location, size or name of the data files when creating tablespaces. Automatically removes files from the OS when tablespace or redo group is dropped. Third party applications need not worry about OS specific file name conventions. I’m personally not a fan of OMF, but I use the INCLUDING CONTENTS AND DATAFILES clause of DROP TABLESPACE to remove the OS files when a tablespace is dropped. I like this feature. DROP TABLESPACE MYTS INCLUDING CONTENTS AND DATAFILES; Read more about OMF at OTN 9i daily feature – March 20

Also, see Oracle documentation.

******** Using multiple block sizes
This is one of the most exciting new features for the DBA, especially now a day there are many databases where you can hardly distinguish between OLTP and DSS…. In the pre-9i releases, you define the BLOCK_SIZE when creating the database and it cannot be changed. In 9i also this is true. In addition to the standard block size of the database, you can create tablespaces with different block size. The block size of the tablespace is specified using the BLOCK SIZE clause of CREATE TABLESPACE. For you to use this feature, you need to set the right buffer cache parameter. The DB_CACHE_SIZE specifies the buffer cache size for the objects in tablespaces created with the standard block size. DB_nK_CACHE_SIZE parameter sets the appropriate buffer cache for the non-standard block sized tablespace. ‘n’ could be 2, 4, 8, 16 or 32 but it should not be equal to your standard block size. The default values for DB_nK_CACHE_SIZE parameters are 0.
SQL> show parameter db%cache NAME -----------------------------------db_16k_cache_size db_2k_cache_size db_32k_cache_size db_4k_cache_size db_8k_cache_size TYPE ----------big integer big integer big integer big integer big integer VALUE ------0 0 0 0 0

db_cache_advice

db_cache_size db_keep_cache_size db_recycle_cache_size SQL> show parameter db_block NAME -----------------------------------db_block_buffers db_block_checking db_block_checksum db_block_size SQL>

big integer 0 big integer 0 big integer 0 TYPE ----------integer boolean boolean integer

string

OFF

VALUE ------1500 FALSE TRUE 8192

Look at the above parameters; since the database was upgraded from 8i, it is still using the old style buffer cache sizing using DB_BLOCK_BUFFERS. Here we cannot set any of the DB_nK_CACHE_SIZE parameter because you have not used the DB_CACHE_SIZE parameter to start the database.
SQL> alter system set db_4k_cache_size=20; alter system set db_4k_cache_size=20

* ERROR at line 1: ORA-02097: parameter cannot be modified because specified value is invalid ORA-00381: cannot use both new and old parameters for buffer cache size specification

SQL> Let’s try another database:
SQL> show parameter db%cache NAME -----------------------------------db_16k_cache_size db_2k_cache_size db_32k_cache_size db_4k_cache_size db_8k_cache_size db_cache_advice db_cache_size db_keep_cache_size db_recycle_cache_size SQL> show parameter sga TYPE ----------big integer big integer big integer big integer big integer string big integer big integer big integer VALUE -----------0 0 0 0 0 ON 83886080 0 0 VALUE -----------FALSE FALSE 220163984

NAME TYPE ------------------------------------ ----------lock_sga boolean pre_page_sga boolean sga_max_size big integer SQL> SQL> alter system set db_cache_size=20m; System altered. SQL> alter system set db_4k_cache_size=2M; System altered. SQL> show parameter db%cache NAME TYPE ------------------------------------ ----------db_16k_cache_size big integer db_2k_cache_size big integer db_32k_cache_size big integer db_4k_cache_size big integer db_8k_cache_size big integer db_cache_advice string db_cache_size big integer db_keep_cache_size big integer db_recycle_cache_size big integer SQL> SQL> SQL> create tablespace test_biju datafile

VALUE ------------------0 0 0 16777216 0 ON 33554432 0 0

2 3 4* SQL>

'/ora_backup/test_biju.dbf' size 50m extent management local blocksize 4k /

Tablespace created. SQL>

SQL> select block_size from dba_tablespaces
2 where tablespace_name = 'TEST_BIJU'; BLOCK_SIZE ---------4096 1 row selected. SQL> drop tablespace test_biju including contents and datafiles; Tablespace dropped.

******** Multi-table INSERT
Inserts to multiple tables in a single INSERT statement are a significant addition to the Oracle9i database ETL features. This allows the INSERT INTO … SELECT statement to load data to multiple target tables. A single scan can perform inserts to multiple target tables [based on the conditions you specify - optional]. Prior to Oracle9i, you may have to write multiple INSERT statements for each table or use a PL/SQL cursor to insert into different tables. The syntax of multi-table insert is: INSERT { ALL insert_into_clause [values_clause] [insert_into_clause [values_clause]]... | conditional_insert_clause } subquery where the conditional_insert_clause is [ ALL | FIRST ] WHEN condition THEN insert_into_clause [values_clause] [insert_into_clause [values_clause]]... [WHEN condition THEN insert_into_clause [values_clause] [insert_into_clause [values_clause]]... ]...

[ELSE insert_into_clause [values_clause] [insert_into_clause [values_clause]]... ] The INSERT ALL clause inserts rows into the target tables unconditionally. Each row read is processed against each INSERT clause. The following example takes each row from SALES_HISTORY table and inserts into the SALES_MONTHLY table a total amount for each month (flat table to a normalized table):
DESC SALES_HISTORY Name Null? ----------------------------------------- -------YEAR REGION JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC DESC SALES_MONTHLY Name Null? ----------------------------------------- -------MONTH_YEAR AMOUNT Type ------------NUMBER(4) CHAR (2) NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER NUMBER Type ------------DATE NUMBER

INSERT ALL INTO SALES_MONTHLY (MONTH_YEAR, AMOUNT) VALUES (TO_DATE('01/'||YEAR,'MM/YYYY'), JAN) INTO SALES_MONTHLY VALUES (TO_DATE('02/'||YEAR,'MM/YYYY'), FEB) INTO SALES_MONTHLY VALUES (TO_DATE('03/'||YEAR,'MM/YYYY'), MAR) INTO SALES_MONTHLY VALUES (TO_DATE('04/'||YEAR,'MM/YYYY'), APR) INTO SALES_MONTHLY VALUES (TO_DATE('05/'||YEAR,'MM/YYYY'), MAY) INTO SALES_MONTHLY VALUES (TO_DATE('06/'||YEAR,'MM/YYYY'), JUN) INTO SALES_MONTHLY VALUES (TO_DATE('07/'||YEAR,'MM/YYYY'), JUL) INTO SALES_MONTHLY VALUES (TO_DATE('08/'||YEAR,'MM/YYYY'), AUG) INTO SALES_MONTHLY VALUES (TO_DATE('09/'||YEAR,'MM/YYYY'), SEP) INTO SALES_MONTHLY VALUES (TO_DATE('10/'||YEAR,'MM/YYYY'), OCT) INTO SALES_MONTHLY VALUES (TO_DATE('11/'||YEAR,'MM/YYYY'), NOV) INTO SALES_MONTHLY VALUES (TO_DATE('12/'||YEAR,'MM/YYYY'), DEC) SELECT YEAR, SUM(JAN) JAN, SUM(FEB) FEB, SUM(MAR) MAR, SUM(APR) APR, SUM(MAY) MAY, SUM(JUN) JUN, SUM(JUL) JUL, SUM(AUG) AUG, SUM(SEP) SEP, SUM(OCT) OCT, SUM(NOV) NOV, SUM(DEC) DEC FROM SALES_HISTORY

GROUP BY YEAR /

The ALL in the conditional insert clause makes Oracle evaluate all the WHEN conditions irrespective of the other WHEN conditions. The FIRST clause stops evaluating other WHEN conditions the first time any condition is evaluated true. The conditions are evaluated in the order they appear.
INSERT FIRST WHEN REGION = 'TX' THEN INTO SALES_TEXAS (YEAR, TOTAL_AMOUNT) VALUES (YEAR, TOTAMT) WHEN REGION = 'CA' THEN INTO SALES_CALIF (YEAR, TOTAL_AMOUNT) VALUES (YEAR, TOTAMT) WHEN REGION = 'NM' THEN INTO SALES_NEWMEX (YEAR, TOTAL_AMOUNT) VALUES (YEAR, TOTAMT) WHEN REGION = 'AZ' THEN INTO SALES_ARIZ (YEAR, TOTAL_AMOUNT) VALUES (YEAR, TOTAMT) ELSE INTO SALES_OTHER (YEAR, TOTAL_AMOUNT) VALUES (YEAR, TOTAMT) SELECT YEAR, REGION, (JAN+FEB+MAR+APR+MAY+JUN+JUL+AUG+SEP+OCT+NOV+DEC) TOTAMT FROM SALES_HISTORY /

If the ELSE clause is omitted, Oracle takes no action on that row.

******** Index Skip Scan
In pre-Oracle9i releases a composite index could only be used if the leading edge column of the index was referenced in the WHERE clause of a statement. In Oracle9i this restriction is removed because the optimizer can perform skip scans to retrieve rowids for values that do not use the prefix. Skip scanning lets a composite index be split logically into smaller sub-indexes. Skip scanning is advantageous if there are few distinct values in the leading column of the composite index and many distinct values in the non-leading key of the index. The index and table must be analyzed for Oracle to take advantage of index skip scan. SQL> SQL> create table test as 2 select * from dba_objects; Table created.

SQL> create index test_i1 on test (owner, object_name); Index created. SQL> SQL> 2 3 set autotrace on select object_type, object_name from test where object_name = 'DWA_JOB_LOG';

OBJECT_TYPE OBJECT_NAME ------------------ ------------------------TABLE DW_JOB_LOG 1 row selected. Execution Plan ---------------------------------------------------------0 SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (FULL) OF 'TEST' SQL> SQL> analyze table test compute statistics; Table analyzed. SQL> 2 3* SQL> select object_type, object_name from test where object_name = 'DWA_JOB_LOG' /

OBJECT_TYPE OBJECT_NAME ------------------ ------------------------TABLE DW_JOB_LOG 1 row selected.
Execution Plan ---------------------------------------------------------0 SELECT STATEMENT Optimizer=CHOOSE (Cost=46 Card=2 Bytes=62) 1 0 TABLE ACCESS (BY INDEX ROWID) OF 'TEST' (Cost=46 Card=2 By tes=62) 2 1 INDEX (SKIP SCAN) OF 'TEST_I1' (NON-UNIQUE) (Cost=45 Card=2)

SQL>

******** DBMS_METADATA
DBMS_METADATA is a powerful package provided in Oracle9i to extract the object definitions from the database. The following are the programs available in the package:

Subprogram OPEN Procedure

Description Specifies the type of object to be retrieved, the version of its metadata, and the object model. Specifies restrictions on the objects to be retrieved, for example, the object name or schema. Specifies the maximum number of objects to be retrieved in a single FETCH_xxx call. Returns the text of the queries that are used by FETCH_xxx. Enables output parsing by specifying an object attribute to be parsed and returned. Specifies a transform that FETCH_xxx applies to the XML representation of the retrieved objects. Specifies parameters to the XSLT stylesheet identified by transform_handle. Returns metadata for objects meeting the criteria established by OPEN, SET_FILTER, SET_COUNT, ADD_TRANSFORM, and so on. Invalidates the handle returned by OPEN and cleans up the associated state.

SET_FILTER Procedure

SET_COUNT Procedure

GET_QUERY Procedure SET_PARSE_ITEM Procedure

ADD_TRANSFORM Procedure

SET_TRANSFORM_PARAM Procedure FETCH_xxx Procedure

CLOSE Procedure

GET_XML and GET_DDL Functions Returns the metadata for the specified object as XML or DDL. GET_DEPENDENT_XML and Returns the metadata for one or more GET_DEPENDENT_DDL Functions dependent objects, specified as XML or DDL. GET_GRANTED_XML and GET_GRANTED_DDL Functions Returns the metadata for one or more granted objects, specified as XML or DDL.

Here is an example:

SQL> EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM (DBMS_METADATA.SESSION_TRANSFORM, 'STORAGE',false);
PL/SQL procedure successfully completed. SQL> SQL> SELECT DBMS_METADATA.GET_DDL('TABLE','SALES_HISTORY') FROM DUAL; DBMS_METADATA.GET_DDL('TABLE','SALES_HISTORY') ------------------------------------------------------CREATE TABLE "MYUSER"."SALES_HISTORY" ( "YEAR" NUMBER(4,0), "JAN" NUMBER, 1 row selected. SQL> set long 32000 SQL> SELECT DBMS_METADATA.GET_DDL('TABLE','SALES_HISTORY') FROM DUAL; DBMS_METADATA.GET_DDL('TABLE','SALES_HISTORY') -----------------------------------------------------------------CREATE TABLE "MYUSER"."SALES_HISTORY" ( "YEAR" NUMBER(4,0), "JAN" NUMBER, "FEB" NUMBER, "MAR" NUMBER, "APR" NUMBER, "MAY" NUMBER, "JUN" NUMBER, "JUL" NUMBER, "AUG" NUMBER, "SEP" NUMBER, "OCT" NUMBER, "NOV" NUMBER, "DEC" NUMBER, "REGION" CHAR(2) ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING TABLESPACE "USERS" 1 row selected. SQL>

SET_TRANSFORM_PARAM: Transform Parameters for the DDL Transform
Object Type Name Datatype Meaning Boolean If TRUE, format the output with indentation and line feeds. Defaults to TRUE.

All objects PRETTY

Object Type

Name
SQLTERMINATOR

Datatype Meaning Boolean If TRUE, append a SQL terminator (; or /) to each DDL statement. Defaults to FALSE. Boolean If TRUE, emit segment attributes (physical attributes, storage attributes, tablespace, logging). Defaults to TRUE. Boolean If TRUE, emit storage clause. (Ignored if SEGMENT_ATTRIBUTES is FALSE.) Defaults to TRUE. Boolean If TRUE, emit tablespace. (Ignored if SEGMENT_ATTRIBUTES is FALSE.) Defaults to TRUE. Boolean If TRUE, emit all nonreferential table constraints. Defaults to TRUE. Boolean If TRUE, emit all referential constraints (foreign key and scoped refs). Defaults to TRUE. Boolean If TRUE, emit table constraints as separate ALTER TABLE (and, if necessary, CREATE INDEX) statements. If FALSE, specify table constraints as part of the CREATE TABLE statement. Defaults to FALSE. Requires that CONSTRAINTS be TRUE. Boolean If TRUE, emit the OID clause for object tables. Defaults to FALSE. Boolean If TRUE, emit the BYTE keyword as part of the size specification of CHAR and

TABLE

SEGMENT_ATTRIBUTES

STORAGE

TABLESPACE

TABLE

CONSTRAINTS

REF_CONSTRAINTS

CONSTRAINTS_AS_ALTER

OID

SIZE_BYTE_KEYWORD

Object Type

Name

Datatype Meaning columns that use byte semantics. If FALSE, omit the keyword. Defaults to
VARCHAR2 FALSE.

INDEX

SEGMENT_ATTRIBUTES

Boolean If TRUE, emit segment attributes (physical attributes, storage attributes, tablespace, logging). Defaults to TRUE. Boolean If TRUE, emit storage clause. (Ignored if SEGMENT_ATTRIBUTES is FALSE.) Defaults to TRUE. Boolean If TRUE, emit tablespace. (Ignored if SEGMENT_ATTRIBUTES is FALSE.) Defaults to TRUE. Boolean If TRUE, emit the type specification. Defaults to TRUE. Boolean If TRUE, emit the type body. Defaults to TRUE. Boolean If TRUE, emit the package specification. Defaults to TRUE. Boolean If TRUE, emit the package body. Defaults to TRUE. Boolea If TRUE, use the FORCE keyword in the CREATE VIEW statement. Defaults to TRUE.

STORAGE

TABLESPACE

TYPE

SPECIFICATION

BODY

PACKAGE SPECIFICATION

BODY

VIEW

FORCE

All objects DEFAULT

Boolean Calling SET_TRANSFORM_PARAM with this parameter set to TRUE has the effect of resetting all parameters for the transform to their default values. Setting this FALSE has no effect. There is no

Object Type

Name
INHERIT

Datatype Meaning default. Boolean If TRUE, inherits session-level parameters. Defaults to FALSE. If an application calls ADD_TRANSFORM to add the DDL transform, then by default the only transform parameters that apply are those explicitly set for that transform handle. This has no effect if the transform handle is the session transform handle.

The two tables on this page are excerpt from Oracle documentation – “PL/SQL Supplied Packages”

******** DBMS_XPLAN
Remember the SQL you use to get the explain plan from the PLAN_TABLE and you perform and EXPLAIN on a statement: SELECT LPAD(' ', 2*level) || operation ||' ' || options ||' ' || object_name || ' COST=' || cost "Execution Plan" FROM plan_table CONNECT BY PRIOR id = parent_id START WITH ID = 1 Well, you may never use the above SQL, Oracle9i gives you a package to look at the explain plans – DBMS_XPLAN. Here is an example:
SQL> EXPLAIN PLAN FOR 3 from test 4* where object_name = 'DWA_JOB_LOG' SQL> / Explained.

2

select object_type, object_name

SQL> SELECT * FROM TABLE(dbms_xplan.display); PLAN_TABLE_OUTPUT ---------------------------------------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost | --------------------------------------------------------------------------| 0 | SELECT STATEMENT | | 2 | 62 | 46 | | 1 | TABLE ACCESS BY INDEX ROWID| TEST | 2 | 62 | 46 | |* 2 | INDEX SKIP SCAN | TEST_I1 | 2 | | 45 | ---------------------------------------------------------------------------

Predicate Information (identified by operation id): --------------------------------------------------2 - access("TEST"."OBJECT_NAME"='DWA_JOB_LOG')

filter("TEST"."OBJECT_NAME"='DWA_JOB_LOG')
Note: cpu costing is off 16 rows selected. SQL> SQL> alter table test parallel; Table altered. SQL> delete from plan_table; 3 rows deleted. SQL> commit; Commit complete. SQL> 2 3 4 5 EXPLAIN PLAN FOR select object_type, object_name from test where object_name = 'DWA_JOB_LOG' /

Explained. SQL> SELECT * FROM TABLE(dbms_xplan.display);

PLAN_TABLE_OUTPUT

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| Id | Operation | Name | Rows | Bytes | Cost | TQ |IN-OUT| PQ Distrib | ------------------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 2 | 62 | 5 | | | | |* 1 | TABLE ACCESS FULL | TEST | 2 | 62 | 5 | 80,00 | P->S | QC (RAND) | -----------------------------------------------------------------------------------------------Predicate Information (identified by operation id): --------------------------------------------------1 - filter("TEST"."OBJECT_NAME"='DWA_JOB_LOG') Note: cpu costing is off 14 rows selected. SQL>

The following are the parameters of DBMS_XPLAN.DISPLAY procedure: DBMS_XPLAN.DISPLAY( table_name IN statement_id IN format IN VARCHAR2 VARCHAR2 VARCHAR2 DEFAULT 'PLAN_TABLE', DEFAULT NULL, DEFAULT 'TYPICAL');

******** ANSI Style Outer Joins
If you’re one of those people who always get confused on where to put the (+) for an outer join, here is relief for you. Oracle9i supports the ANSI style outer join syntax. You can now use the English like meaningful keywords and even do an outer join from both tables (full join). The following are excerpts from Oracle Documentation – SQL Reference Guide

New Outer Join Syntax
An outer join extends the result of a simple join. An outer join returns all rows that satisfy the join condition and also returns some or all of those rows from one table for which no rows from the other satisfy the join condition. To write a query that performs an outer join of tables A and B and returns all rows from A (a left outer join), use the LEFT [OUTER] JOIN syntax in the FROM clause, or apply the outer join operator (+) to all columns of B in the join condition in the WHERE clause. For all rows in A that have no matching rows in B, Oracle returns null for any select list expressions containing columns of B. To write a query that performs an outer join of tables A and B and returns all rows from B (a right outer join), use the RIGHT [OUTER]

syntax in the FROM clause, or apply the outer join operator (+) to all columns of A in the join condition in the WHERE clause. For all rows in B that have no matching rows in A, Oracle returns null for any select list expressions containing columns of A. To write a query that performs an outer join and returns all rows from A and B, extended with nulls if they do not satisfy the join condition (a full outer join), use the FULL [OUTER] JOIN syntax in the FROM clause.
JOIN Oracle Corporation recommends that you use the FROM clause OUTER JOIN syntax rather than the Oracle join operator. Outer join queries that use the Oracle join operator (+) are subject to the following rules and restrictions, which do not apply to the FROM clause join syntax:

You cannot specify the (+) operator in a query block that also contains FROM clause join syntax. The (+) operator can appear only in the WHERE clause or, in the context of left-correlation (that is, when specifying the TABLE clause) in the FROM clause, and can be applied only to a column of a table or view. If A and B are joined by multiple join conditions, then you must use the (+) operator in all of these conditions. If you do not, then Oracle will return only the rows resulting from a simple join, but without a warning or error to advise you that you do not have the results of an outer join. The (+) operator does not produce an outer join if you specify one table in the outer query and the other table in an inner query. You cannot use the (+) operator to outer-join a table to itself, although self joins are valid. For example, the following statement is not valid: -- The following statement is not valid: SELECT employee_id, manager_id FROM employees WHERE employees.manager_id(+) = employees.employee_id; However, the following self join is valid: SELECT e1.employee_id, e1.manager_id, e2.employee_id FROM employees e1, employees e2 WHERE e1.manager_id(+) = e2.employee_id; The (+) operator can be applied only to a column, not to an arbitrary

expression. However, an arbitrary expression can contain one or more columns marked with the (+) operator. A condition containing the (+) operator cannot be combined with another condition using the OR logical operator. A condition cannot use the IN comparison condition to compare a column marked with the (+) operator with an expression. A condition cannot compare any column marked with the (+) operator with a subquery. If the WHERE clause contains a condition that compares a column from table B with a constant, then the (+) operator must be applied to the column so that Oracle returns the rows from table A for which it has generated nulls for this column. Otherwise Oracle will return only the results of a simple join. In a query that performs outer joins of more than two pairs of tables, a single table can be the null-generated table for only one other table. For this reason, you cannot apply the (+) operator to columns of B in the join condition for A and B and the join condition for B and C.

Using Outer Joins: Examples
The following example uses a left outer join to return the names of all departments in the sample schema hr, even if no employees have been assigned to the departments:
SELECT d.department_id, e.last_name FROM departments d LEFT OUTER JOIN employees e ON d.department_id = e.department_id ORDER BY d.department_id; DEPARTMENT_ID ------------10 20 20 30 LAST_NAME ------------------------Whalen Hartstein Fay Raphaely

...

250 260 270

Users familiar with the traditional Oracle outer joins syntax will recognize the same query in this form:
SELECT d.department_id, e.last_name FROM departments d, employees e WHERE d.department_id = e.department_id(+) ORDER BY d.department_id;

The left outer join returns all departments, including those without any employees. The same statement with a right outer join returns all employees, including those not yet assigned to a department:
SELECT d.department_id, e.last_name FROM departments d RIGHT OUTER JOIN employees e ON d.department_id = e.department_id ORDER BY d.department_id; DEPARTMENT_ID ------------... 110 110 LAST_NAME ------------------------Higgins Gietz Grant Zeuss

It is not clear from this result whether employees Grant and Zeuss have department_id NULL, or whether their department_id is not in the departments table. To determine this requires a full outer join:
SELECT d.department_id as d_dept_id, e.department_id as e_dept_id, e.last_name FROM departments d FULL OUTER JOIN employees e ON d.department_id = e.department_id ORDER BY d.department_id; D_DEPT_ID ... ... 110 110 260 270 E_DEPT_ID LAST_NAME 110 Gietz 110 Higgins

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

999 Zeuss Grant

Because the column names in this example are the same in both tables in the join, you can also use the common column feature (the USING clause) of the join syntax, which coalesces the two matching columns department_id. The output is the same as for the preceding example:
SELECT department_id AS d_e_dept_id, e.last_name FROM departments d FULL OUTER JOIN employees e USING (department_id) ORDER BY department_id; D_E_DEPT_ID ----------... 110 110 LAST_NAME ------------------------Higgins Gietz

...

260 270

Grant Zeuss

******** Random Sampling of Data
The SELECT statement in Oracle9i provides the SAMPLE clause to read a random sample of data from table. SELECT ...table_name SAMPLE [BLOCK] ( sample_percent ) You can sample the rows based on a random number of blocks instead of random rows. The BLOCK keyword must be included for block sampling. The optional sample percent must be less than 100. When using the SAMPLE clause, the query must select only from one table, join queries are not supported.
SQL >select count(*) from test sample (1); COUNT(*) ---------341 1 row selected. SQL >select count(*) from test; COUNT(*) ---------33574 1 row selected. SQL > select count(*) * 100 from test sample (1); COUNT(*)*100 -----------35000 1 row selected. SQL >

******** New Data Types

******** “Upsert” or the MERGE statement
MERGE is a new SQL statement introduced in Oracle9i to update or insert rows selected from one table to another based on a condition. This avoids writing multiple DML statements to satisfy a conditional update or insert. The syntax is:
MERGE [hint] INTO [schema .] table [t_alias] USING [schema .] { table | view | subquery } [t_alias] ON ( condition ) WHEN MATCHED THEN UPDATE SET column = { expr | DEFAULT } [, column = { expr | DEFAULT }]... WHEN NOT MATCHED THEN INSERT ( column [, column]... ) VALUES ( expr [, expr]... )

MERGE
Purpose
Use the MERGE statement to select rows from one table for update or insertion into another table. The decision whether to update or insert into the target table is based on a condition in the ON clause. This statement is a convenient way to combine at least two operations. It lets you avoid multiple INSERT and UPDATE DML statements. is a deterministic statement. That is, you cannot update the same row of the target table multiple times in the same MERGE statement.
MERGE

Prerequisites
You must have INSERT and UPDATE object privileges on the target table and SELECT privilege on the source table.

Syntax
merge::=

Syntax
merge::=

Text description of merge merge_update_clause::=

Text description of merge_update_clause merge_insert_clause::=

Text description of merge_insert_clause

Semantics
INTO Clause Use the INTO clause to specify the target table you are updating or inserting into. USING Clause Use the USING clause to specify the source of the data to be updated or inserted. The source can be a table, view, or the result of a subquery. ON Clause Use the ON clause to specify the condition upon which the MERGE operation either updates or inserts. For each row in the target table for which the search condition is true, Oracle updates the row based with corresponding data from the source table. If the condition is

not true for any rows, then Oracle inserts into the target table based on the corresponding source table row. WHEN MATCHED | NOT MATCHED Use these clauses to instruct Oracle how to respond to the results of the join condition in the ON clause. You can specify these two clauses in either order.

merge_update_clause
The merge_update_clause specifies the new column values of the target table. Oracle performs this update if the condition of the ON clause is true. If the update clause is executed, then all update triggers defined on the target table are activated.

Restrictions on Updating a View
• •

You cannot specify DEFAULT when updating a view. You cannot update a column that is referenced in the ON condition clause.

merge_insert_clause
The merge_insert_clause specifies values to insert into the column of the target table if the condition of the ON clause is false. If the insert clause is executed, then all insert triggers defined on the target table are activated.

Restriction on Merging into a View
You cannot specify DEFAULT when updating a view.

Examples Merging into a Table: Example
The following example creates a bonuses table in the sample schema oe with a default bonus of 100. It then inserts into the bonuses table all employees who made sales (based on the sales_rep_id column of the oe.orders table). Finally, the Human Resources manager decides that all employees should receive a bonus. Those who have not made sales get a bonus of 1% of their salary. Those who already made sales get an increase in their bonus equal to 1% of their salary. The MERGE statement implements these changes in one step:
CREATE TABLE bonuses (employee_id NUMBER, bonus NUMBER DEFAULT 100); INSERT INTO bonuses(employee_id) (SELECT e.employee_id FROM employees e, orders o WHERE e.employee_id = o.sales_rep_id GROUP BY e.employee_id);

SELECT * FROM bonuses; EMPLOYEE_ID BONUS ----------- ---------153 100 154 100 155 100 156 100 158 100 159 100 160 100 161 100 163 100 MERGE INTO bonuses D USING (SELECT employee_id, salary, department_id FROM employees WHERE department_id = 80) S ON (D.employee_id = S.employee_id) WHEN MATCHED THEN UPDATE SET D.bonus = D.bonus + S.salary*.01 WHEN NOT MATCHED THEN INSERT (D.employee_id, D.bonus) VALUES (S.employee_id, S.salary*0.1); EMPLOYEE_ID BONUS ----------- ---------153 180 154 175 155 170 156 200 158 190 159 180 160 175 161 170 163 195 157 950 145 1400 170 960 179 620 152 900 169 1000 .

DO U KNOW
In PL/SQL you can suspend a session using

1998/10

dbms_lock.sleep (seconds) which is equivalent to the 'sleep' command in UNIX. The parameter (number data type) can even be specified in hundredth of a second (10, 10.01, 10.5, 0.99 are all legal values). When you TRUNCATE a table, the storage parameter NEXT is automatically reset to the last extent deleted. Similarly when you de-allocate extents from a table, the NEXT is automatically reset to the size of the last extent deallocated.
1998/11

In PL/SQL you can assign a rollback segment to a transaction (without using dynamic sql) by utilizing the Oracle supplied package dbms_transaction.use_rollback_segment ('rbs_name').
1998/12

The SQL select to_char(to_date(123456,'J'), 'JSP') from dual; can be used to convert numbers to words, here is the result: ONE HUNDRED TWENTY-THREE THOUSAND FOUR HUNDRED FIFTYSIX.
1999/01

To find the difference between date columns in Days, Hours, Minutes & Seconds use the SQL - Select trunc(date2 - date1) days, to_char( to_date( trunc( mod(date2-date1,1) * 86400), 'SSSSS'), 'HH24:MI:SS') time from tablename;
1999/02

The file sgadefSID.dbf is created at instance startup in $ORACLE_HOME/dbs directory and its function is to store the address of the memory location of the SGA. When the instance is shutdown, this file is deleted.
1999/03

In oracle7, you have to query the table SYS.FILEXT$ to find if AUTOEXTEND feature for a file is enabled and this table is only created if the AUTOEXTEND feature is ever turned on in any datafile in the database. The values for MAXEXTEND (max file size) and INC (increment) are expressed in BLOCKS. In Oracle8, the DBA_DATA_FILES view has this info.
1999/04 1999/05 In oracle8i, to drop a column from a table, you no longer have to create a temp table and do insert!! Cool!! The drop column clause in ALTER TABLE lets you free space in the database by dropping columns you no longer need, or by marking them to be dropped at a future time when the demand on system resources is less. You can view the tables with columns marked unusable in DBA_UNUSED_COL_TABS. 1999/06

In oracle8i, you can fire a trigger on database STARTUP,

SHUTDOWN, SERVERERROR; user LOGON, LOGOFF; object CREATE, ALTER, DROP. The trigger defined in database level will fire for all users and schema level will fire only for the specific user when the event occurs. In oracle8i, there is a new option available to shutdown database "SHUTDOWN TRANSACTIONAL". After submitting this statement, no client can start a new transaction on this instance. If clients attempt to start a new transaction, they are disconnected. After all transactions have completed, any client still connected to the instance is disconnected.
1999/07

In oracle8i, you can create temporary tables, which are created in users temporary tablespace. Its definition is visible to all sessions but the data is visible to, and can be queried by, only the session that inserts the data into the table.
1999/08 1999/09 In oracle8i, you can reorganize a non-partitioned table without doing export and import. The table can be moved from one tablespace to another also, operation requires double the amount of space. (ALTER TABLE mytable MOVE TABLESPACE newtablespace;) 1999/10 In oracle8i, TRIM function is available, which is a combination of the existing LTRIM and RTRIM functions, allowing the user to trim leading and trailing characters from a character string. 1999/11 In Oracle 8i, you can create an index reverse keyed [CREATE INDEX i ON t (a,b,c) REVERSE;]. Since lexically adjacent keys are not stored next to each other in a reverse-key index, only fetch-by-key or full-index (table) scans can be performed. 1999/12 In Oracle8, the V$INSTANCE system view has many useful information like the hostname, startup time, version, etc.

Oracle error codes from 10000 to 10999 are pseudo-error messges which are used for setting event traces to debug.
2000/01

A temporary segment created on a TEMPORARY tablespace is released only at shutdown, the temporary segments are reused; whereas a temporary segment created on a PERMANENT tablespace is cleaned up by the SMON process once the completion of the statement and the space is released.
2000/02 2000/03 In Oracle8i, on most of the UNIX platforms, the sgadefSID.dbf is not created when the database is started. If you

use sgadefSID.dbf in the scripts to verify if the database is up, you may need to look for the pmon_SID process from now on.
2000/04 The V$RESERVED_WORDS system view has all the keywords that are reserved by Oracle. 2000/05 In Oracle8i, you need not recreate the control file to adjust MAXDATAFILES defined at database creation, when increasing the DB_FILES parameter, Oracle automatically adjusts the control file.

In Oracle8i, you can specify up to 5 archive log destinations using the LOG_ARCHIVE_DEST_n parameter.
2000/06 2000/07 In release 8.1.6, block checking and checksums are turned on for the SYSTEM tablespace, allowing the Oracle server to detect and repair any SYSTEM tablespace corruptions before they are written to disk.

OUTLN schema in Oracle8i database has a default password of OUTLN. This schema has some powerful privileges and hence the password must be changed.
2000/08

Statspack collects high-resource SQL whereas UTLESTAT does not.
2000/09

You can upload the utlestat reports and statspack reports to www.oraperf.com for analyzing.
2000/10 2000/11 In Oracle8i, ALTER SYSTEM SUSPEND statement can suspend all I/O operations of the database, enabling hot backups using OS mirror splits.

In Oracle8i, use $ORACLE_HOME/rdbms/admin/utlrp.sql script to recompile all invalid PL/SQL stored programs, triggers and views. You must connect as SYS or INTERNAL.
2000/12 2001/01 In Oracle8i, you can execute DDL commands inside PL/SQL block using the "EXECUTE IMMEDIATE" statement. Prior to 8i, you need to parse and execute the command using the DBMS_SQL package. 2001/02 In Oracle8i, temporary tables can be created using CREATE GLOBAL TEMPORARY TABLE statement, data in such tables are visible only to the session that inserts rows. Rows are deleted at the end of transaction or end of session (based on the ON COMMIT clause table definition). 2001/03

You can move a table from one tablespace to another using

the MOVE clause of ALTER TABLE statement. All indexes of moved table need to be rebuilt.
2001/04 In Oracle8i, non-unique indexes can be created to enforce unique and primary key constraints. 2001/05 In Oracle7, SELECT ANY TABLE privilege gave access to dictionary views such as DBA_ and V$ views. In Oracle8i, you need to set O7_DICTIONARY_ACCESSIBILITY=TRUE to achieve this behavior. The new predefined roles SELECT_CATALOG_ROLE and EXECUTE_CATALOG_ROLE can be used in 8i.

Composite partitioning in Oracle8i uses range partitioning for partitions and hash partitioning for sub-partitions. Only subpartitions store data.
2001/06 2001/07 Oracle8i 8.1.6 release on UNIX platforms do not have the "sqlload" executable, instead comes with "sqlldr" executable. If your scripts are using "sqlload", you need to make a soft link using "ln -s sqlldr sqlload" 2001/08 With Oracle8i 8.1.7, a new tool named iSQL*Plus is available, which is a browser based SQL*Plus tool. No need to install client software on every PC to use SQL*Plus!!

Oracle9i supports ANSI SQL99 standard for specifying join between tables. You can use NATURAL JOIN, CROSS JOIN, JOIN ON, JOIN USING, LEFT OUTER JOIN, RIGHT OUTER JOIN and FULL JOIN syntaxes.
2001/09

The TIMESTAMP data type in Oracle9i can store Date/Time values with up to 9 digits precision for seconds. TIMESTAMP WITH [LOCAL] TIME ZONE data type can also store time zone information.
2001/10

In Oracle9i, you can define primary key, unique key and foreign key constraints on views. These constraints are declarative hence the only valid state is DISABLE NOVALIDATE.
2001/11 2001/12 In Oracle9i, ALTER INDEX <index name> MONITORING USAGE statement can monitor if an index is used.

In Oracle9i, Server manager tool is not available. You need to use "sqlplus /nolog" instead of "svrmgrl" and "connect / as sysdba" instead of "connect internal".
2002/01 2002/02

In Oracle9i, CASE expression can be used instead of using

complex DECODE functions. Prior to Oracle9i, database buffer cache size was determined by DB_BLOCK_BUFFERS times DB_BLOCK_SIZE. In Oracle9i, the DB_CACHE_SIZE parameter specifies the size.
2002/03

Sign up to vote on this title
UsefulNot useful