To list SQL statements in Shared pool
This can be ordered by number executions, cpu time or disk reads
select sorts, executions, parse_calls, disk_reads, buffer_gets, command_type, cpu_time, elapsed_time from v$sql;
Queries having full table scan of the employee table in scott schema
select sorts, executions, parse_calls, disk_reads, buffer_gets, command_type, cpu_time, elapsed_time
from v$sql where (address, hash_value, child_number) IN(
select address, hash_value, child_number from v$sql_plan where
object_owner='SCOTT' and object_name='EMPLOYEE' and operation='TABLE ACCESS' and options='FULL');
Get Expensive queries
First find the expensive queries in terms of CPU Time or disk reads. Next get the plan of the query. The column plan_hash_value is a Numerical representation of the SQL plan. Comparing one PLAN_HASH_VALUE to another easily identifies whether or not two
plans are the same ( instead of comparing the two plans line by line ). Values can be computed by grouping plan hash values.
Find the expensive plan hash value
select * from(
select plan_hash_value, sum(cpu_time), sum(disk_reads), sum(elapsed_time)
from v$sql group by plan_hash_value order by 3 desc) where rownum<2;
For the above plan_hash_value, say p1, get addres and hash_value of one SQL
select * from(select address, hash_value, child_number from v$sql where plan_hash_value=p1) where rownum<2;
Using the above address and hash_value query the v$sql_plan to get the execution plan for the above query
select * from v$sql_plan where (address, hash_value, child_number) IN
(select * from(select address, hash_value, child_number from v$sql where plan_hash_value=p1) where rownum<2);
Set index monitoring
alter index
To turn off monitoring
alter index
To generate monitoring scripts for all indexes
select 'alter index '||index_name||' monitoring usage;' from user_indexes where index_type='NORMAL';
To turn off monitoring for all indexes
select 'alter index '||index_name||' nomonitoring;' from user_indexes where index_type='NORMAL';
Find unused indexes
select index_name, table_name, monitoring, used from v$object_usage where monitoring='YES' and used='NO';
select * from(
select a.index_name,
round(b.num_distinct*1000/b.sample_size) cardinality,
b.num_distinct
from user_ind_columns a, user_tab_col_statistics b
where a.table_name=b.table_name and a.column_name=b.column_name
and a.column_position=1 and nvl(b.sample_size,0)>100)
where cardinality<2 and num_distinct<6;
Consider the sales table with millions of rows. A partitioned index has to be created based on customer_id. It is decided to have one million rows per index partition.
The following query can be used to select range boundaries for index partition
select * from(
select customer_id, rownum r1 from
(select customer_id from sales order by 1)
)
where mod(r1,1000000)=0 order by r1;
| 0 | 1 |
| 1500000 | 2 |
| 3500000 | 3 |
| 6000000 | 4 |
| 8000000 | 5 |
| 15000000 | 5 |
Create the partitioned index
create index sales_customerid_idx on sales(customer_id)
GLOBAL PARTITION BY RANGE(customer_id)
(PARTITION P1 VALUES LESS THAN( 1500000 ) tablespace ts1,
PARTITION P2 VALUES LESS THAN ( 3500000 ) tablespace ts1,
PARTITION P3 VALUES LESS THAN ( 6000000 ) tablespace ts1,
PARTITION P4 VALUES LESS THAN ( 8000000 ) tablespace ts1,
PARTITION P5 VALUES LESS THAN ( 15000000 ) tablespace ts1,
PARTITION PN VALUES LESS THAN ( maxvalue) tablespace ts1
);
Manage Locks in Oracle
Scripts to generate schema objects
Using Index Fast Full Scan
Using Returning clause
Managing Tablespaces and Datafiles
Script to reorganize tables
Hidden Parameters in Oracle
Using Multiple block sizes for tablespaces
Index Optimization Scripts
Managing Constraints
Oracle Installation
Oracle Tips
Oracle links
Oracle Books
Indexing strategies
Segment usage statistics