Tuesday, July 1, 2014

பெரிய தாதம்பாளையம் ஏரி : சீமைகருவேல மரம்

பெரிய தாதம்பாளையம் ஏரி , இது கரூர் - தாராபுரம் சாலையில் 11 வது Kilometeril உள்ளது. இந்த ஏரியின் பரப்பளவு கிட்டத்தட்ட 300 acres.

 

இந்த ஏரியின் எல்லைகளாக பெரிய தாதம்பாளையம் , சின்ன தாதம்பாளையம் ,பள்ளமருதபட்டி, கொத்தம்பாளையம் உள்ளன.
இதன் பெரிய மதகு பெரிய தாதம்பாளையத்திலும்  , அவசர கால மதகு சின்ன  தாதம்பாளையத்திலும் உள்ளது. இந்த ஏரிக்கு வரும் வாய்க்கால் சின்னதாராபுரம் அருகே தொடங்கி  கொத்தம்பாளையம் அருகே முடிகிறது(30 Kilometers).
( Google Map)

 


15 வருடங்களுக்கு முன்பு வரை , மழை காலங்களில் இங்கு ஏராளமான கொக்கு, நாரை மட்டும் சில வெளிநாட்டுப் பறைவகளும் இங்கு வந்து தங்கி இனப்பெருக்கம் செய்தன. இப்பொழுது எதுவுமே இங்கு வருவதில்லை. இந்த ஏரியில் படகில் மீன் பிடித்த காலமும் உண்டு என்பது குறிப்பிடத்தக்கது.


பெரிய மதகு  (photo)



( தூர்ந்த நிலையில் இன்று இருக்கும் பெரிய மதகு)


(எவ்வளவு நீர் ஏரியில் இருந்து வெளியேறுகிறது என்பதை அளக்கும் அளவுகோல், தூர்ந்த நிலையில் இன்று)


அவசர கால மதகு (photo)








( மிக உறுதியான கருங்கல் சுவர்,ஏரியின் கரைகள்.)



நீர் வரத்து வாய்க்கால் (photo)












( ஒரு காலத்தில் இங்கு தண்ணீர் வந்ததற்கான சான்று, இந்த ஆற்று மண், சுமார் 5-7 அடி வரை ஆற்று மண் நிரம்பி உள்ளது)..

ஏரியின் தோற்றம்(photo).





















20 வருடங்களுக்கு முன்பு  வரை இந்த ஏரியில்  தண்ணீர் தேங்கி சுற்று  வட்டார கிராமங்களின் தண்ணீர் தேவையை பூர்த்தி செய்தது.
இந்த மதகு நீர் பெரிய தாதம்பாளையம் ,கரூர் ராஜவாய்காலில்  சென்று  முடிகிறது. இதன் மூலம் 1000 கணக்கான acre விவசாய நிலங்களும், கரூர் வரையிலான  நிலத்தடி நீரும் நன்கு இருந்தன.

இந்த ஏரிக்கு தண்ணீர் வரத்து அமராவதி ஆற்றில் சின்ன தாராபுரம் அருகே தொடங்கி, வரும் வழியில் 50 க்கும் மேற்பட்ட குளங்களை
 நிரப்பி இறுதியில் இங்கு வந்து சேருகிறது. வரும் வழியில் உள்ள 30+ ஊர்களின் மழை நீர் வடிகாலாகவும் இது இருந்து வந்தது.
 

இதன் இப்போதைய நிலை, ஆற்றில் இருந்து வரும் வாய்க்கால் மண் மூடியும், நில ஆக்கிரமப்பாலர்களால் அபகரிக்கப்பட்டும், தூர் வாரப்படாமலும் கிடக்கிறது. சில இடங்களில் இந்த வாய்க்காலின் தொடர்ச்சி அற்றுப்போயும் உள்ளது.

அத்துடன், இந்த ஏரியும் 100க் கணக்கான  வருடங்களாக  தூர் வாரப்படாமல், மறு  புணரமைப்பு பன்னாமலும் தூர்ந்து போய் உள்ளது.  இதனால் ஏரி  முழுவதும் சீமை கருவேல மரங்கள் முளைத்துக்கிடக்கிறது.

 இதனால் சுற்றுவட்டார  அளவில்  நிலத்தடி நீர் அதளாபாலத்துக்கு சென்று விட்டது.இதனால் கிணற்று நீர் மட்டமும் குறைந்து விட்டது.வறட்சி , கடுமையான வெப்பம் , மற்றும் குடிநீர் பற்றாக்குறை இங்கு தலை விரித்தாடுகிறது. சில ஆண்டுகளுக்கு முன்னால் இந்த ஏரி , ஃபாரெஸ்ட் கட்டுப்பாட்டுக்கு  கொண்டு வரப்பட்டு , சில பகுதிகளில் இந்த சீமை கருவேல மரங்கள் அழிக்கப்பட்டு வேறு மரங்கள் நடப்பட்டன. இருந்தும் மழை இல்லாத காரணத்தால் அவை நான்கு வளரவில்லை, சில இடங்களில் அழிந்தும் போய்விட்டன.இதன் விதைகள் காற்றில் பரவி , விவசாய நிலம் முழுவதும் முளைத்து விடுகின்றன.


இந்த ஏரியை மீண்டும் சீரமைப்பதான் மூலம், கரூர் மற்றும் அதன் சுற்று வட்டார கிராமங்கல் குடிநீர் வசதி பெறலாம், நிலத்தடி மட்டம் நன்கு உயரும், சின்ன தாரபுரம் முதல் கரூர் வரையிலான மானாவாரி நிலங்கள் பாசன வசதி பெரும்.


இந்த முயற்ச்சியை , எங்கள் ஊர் விவசாய நண்பர்கள் ஆக்கப் பூர்வமாக செய்கின்றாம். கலெக்டர் மட்டும் வீவசாய  அதிகாரீகளை சந்தித்து மனுக்கள் கொடுத்து உள்ளன. இதை பற்றி தினமலர் நாளிதழில் செய்தியும் வந்தது.ஆனால் இது வரை எந்த பயனும்   இல்லை .இயற்கை ஆர்வலர்கள் இதற்கு உதவுமாறு எங்கள் ஊர் மக்கள் சார்பாக கேட்டு கொள்கிறேன்.


குறிப்பு : இன்று நாம் சிந்தும் ஒவ்வொரு வியர்வைக்கும் மூல காரணமாக இருப்பவை இந்த கருவேல மரங்கள் தான். 
கருவேல மரங்களின் இலை, காய், விதை போன்றவை எந்த உயிரினத்திற்கும் பயன்படாதவை. இம்மரத்தின் நிழலில் கட்டிவைக்கப்படும் கால்நடைகள் "மலடாக' மாறும் என்பது, சமீபத்தில் கண்டறியப்பட்டுள்ளது. இவற்றின் வேர் நிலத்தடி நீரை விஷமாக மாற்றும் தன்மை கொண்டது. அதே நேரத்தில் இவை முளைத்துள்ள பகுதியில் வேறு செடிகள் வளரமுடியாது. இவற்றின் விஷத்தன்மை அறிந்தே, இதன் மீது எந்த பறவையும் கூடுகட்டுவது இல்லை. ஐந்தறிவு கொண்ட உயிரினங்கள் அனைத்தும், கருவேல மரங்களை ஒட்டுமொத்தமாக புறக்கணித்து வருகின்றன.
எந்த வறட்சியிலும் வளரக்கூடிய தன்மை கருவேல மரங்களுக்கு உண்டு. மழை இல்லாமல் போனாலும் நிலத்தடி நீரை உறிஞ்சி , தனது இலைகளை வாழவிடாமல் பார்த்துக்கொள்கிறது
தன்னை சுற்றி தழுவி வரும் காற்றில் உள்ள ஈரப்பதத்தையும் உறிஞ்சிவிடுகின்றன. இதனால் அப்பகுதியில் வறட்சி என்பது தவிர்க்க முடியாததாகவும், நிலையானதாகவும் மாறிவிடுகிறது.
 

Performence : Tune stat gather and Index rebuild.

Issue :  Running Index stat and table stat gather on the huge database take long time to finish. This
process can be further tunned with the following way.

Pre request :

1)  Grant DBMS_SCHEDULAR Permission to 
-----------------------------------------------------

  Connect to sys user and execute below permission to
       grant all on DBA_SCHEDULER_JOB_RUN_DETAILS to ;
       grant all on DBMS_LOCK to ;
       grant all on DBMS_ISCHED to ;
       grant all on DBMS_SCHEDULER to ;
       grant CREATE ANY JOB to ;

2) connect to schema and run the script
--linux session , cd to file folder where the table_analysis_with_index.sql is placed.

sql> @./table_analysis_with_index.sql

3) calculate the no.of degree and parellal based on the below.

Parallel session can be calculated by using
select * from v$parameter
PARALLEL_DEGREE_POLICY
select * from v$parameter where name like '%cpu%'
select * from v$parameter where name like 'para%'
select * from v$parameter where name like 'para%' or name like '%cpu%'
For a single instance, DOP = PARALLEL_THREADS_PER_CPU x CPU_COUNT
For an Oracle RAC configuration, DOP = PARALLEL_THREADS_PER_CPU x CPU_COUNT x INSTANCE_COUNT
       ALTER SESSION FORCE PARALLEL DDL PARALLEL 8;
       ALTER SESSION FORCE PARALLEL DML PARALLEL 8;
       Note : this will force the DDL/DML operation to run in parallel.
4) script.
copy the below text and make the file table_analysis_with_index.sql

spool ./runstat_details.txt
select systimestamp from dual;
drop table schema_runstat_job_details;
create table schema_runstat_job_details ( job_name varchar2(1000),details varchar2(4000)) ;
alter table schema_runstat_job_details add constraint   schema_runstat_pk primary key  ( job_name); 
 

declare
  p_job_name    varchar2(100) := 'schemastat';
  p_exit        number := 20;
  no_of_session number := 20;
  p_count       number := 0;
begin
  delete from schema_runstat_job_details;
 
  --- call for big tables  separatly.
 
 
 
  for x in (select table_name
              from user_tables where table_name in (,)
              ) loop
    p_job_name := DBMS_SCHEDULER.GENERATE_JOB_NAME('schemastat_');
 
    insert into schema_runstat_job_details
    values
      (p_job_name, x.table_name);
    commit;
    dbms_scheduler.create_job(job_name   => p_job_name,
                              job_type   => 'PLSQL_BLOCK',
                              job_action => 'begin  execute immediate ' ||
                                            '''ALTER SESSION FORCE PARALLEL DDL PARALLEL 5''' || ';
                            DBMS_STATS.gather_table_stats (
        ownname      => ' ||
                                            '''&SCHEMA_NAME''' ||
                                            ',tabname      => ' || '''' ||
                                            x.table_name || '''' ||
                                            ' ,method_opt   => ' || '''' ||
                                            'for all indexed columns size 254' || '''' ||
                                              ',degree      => 5' ||
                                            ',cascade      => FALSE);' || '
                                        
                          exception
                            when others then
                            null;
                   end;',
                              comments   => 'Thread ' || 1 ||
                                            ' for schemastat_',
                              enabled    => true,
                              auto_drop  => FALSE);
end loop;

  --- call for big tables indexs  separatly. 
 
  for x in (select index_name
              from user_indexes where table_name in (,)
              )
              loop
    p_job_name := DBMS_SCHEDULER.GENERATE_JOB_NAME('schemastat_');
 
    insert into schema_runstat_job_details
    values
      (p_job_name, x.index_name);
    commit;
    dbms_scheduler.create_job(job_name   => p_job_name,
                              job_type   => 'PLSQL_BLOCK',
                              job_action => 'begin  execute immediate ' ||
                                            '''ALTER SESSION FORCE PARALLEL DDL PARALLEL 5''' || ';
                            DBMS_STATS.GATHER_INDEX_STATS (
        ownname      => ' ||
                                            '''&SCHEMA_NAME''' ||
                                            ',indname       => ' || '''' ||
                                            x.index_name || '''' ||
                                            ',degree      => 5 );' ||'                                        
                          exception
                            when others then
                            null;
                   end;',
                              comments   => 'Thread ' || 1 ||
                                            ' for schemastat_',
                              enabled    => true,
                              auto_drop  => FALSE);
end loop;

     
for x in (select table_name
              from user_tables where table_name not in (,)
              ) loop
    p_job_name := DBMS_SCHEDULER.GENERATE_JOB_NAME('schemastat_');
 
    insert into schema_runstat_job_details
    values
      (p_job_name, x.table_name);
    commit;
    dbms_scheduler.create_job(job_name   => p_job_name,
                              job_type   => 'PLSQL_BLOCK',
                              job_action => 'begin  execute immediate ' ||
                                            '''ALTER SESSION FORCE PARALLEL DDL PARALLEL 5''' || ';
                            DBMS_STATS.gather_table_stats (
        ownname      => ' ||
                                            '''&SCHEMA_NAME''' ||
                                            ',tabname      => ' || '''' ||
                                            x.table_name || '''' ||
                                            ' ,method_opt   => ' || '''' ||
                                            'for all indexed columns size 254' || '''' ||
                                            ',degree      => 5' ||
                                            ',cascade      => TRUE);' || '
                                        
                          exception
                            when others then
                            null;
                   end;',
                              comments   => 'Thread ' || 1 ||
                                            ' for schemastat_',
                              enabled    => true,
                              auto_drop  => FALSE);
 
    p_exit := no_of_session;
    WHILE (p_exit >= no_of_session) LOOP
   
      select count(*)
        into p_exit
        from dba_scheduler_jobs
       where job_name in (select job_name from schema_runstat_job_details)
         and state in ('SCHEDULED', 'RUNNING');
   
    END LOOP;
  end loop;
end;

/

declare
  p_exit      number:=1;
  job_count number;
begin
WHILE (p_exit<>0)
    LOOP
    select count(*) into job_count from  schema_runstat_job_details;
     select count(*)-job_count
       into p_exit
     from  dba_scheduler_jobs
     where job_name in ( select job_name from schema_runstat_job_details)
        and state in ( 'SUCCEEDED','FAILED');
        DBMS_LOCK.sleep(seconds => 120);
    END LOOP;
end;
/
select systimestamp from dual;

select ' startdate   || end date || time in total ' from dual;
select max_time-min_time total_duration from
(select  max(b.ACTUAL_START_DATE+b.RUN_DURATION )max_time  ,min(b.ACTUAL_START_DATE+b.RUN_DURATION ) min_time from
 DBA_SCHEDULER_JOB_RUN_DETAILS b
     where job_name in ( select job_name from schema_runstat_job_details)
      );
 select a.*,additional_info ,b.ACTUAL_START_DATE,b.RUN_DURATION  from
(
  select  state , job_name,job_action
     from  USER_SCHEDULER_JOBS
     where job_name in ( select job_name from schema_runstat_job_details)
      )A, DBA_SCHEDULER_JOB_RUN_DETAILS B
     where a.job_name=b.job_name
order by RUN_DURATION desc

select table_name,last_analyzed From user_tables where trunc(last_analyzed ) = trunc(sysdate);
select index_name,last_analyzed  from user_indexes
where  trunc(last_analyzed ) = trunc(sysdate) ;
--drop table schema_runstat_job_details;
 
spool off;

6)

3) checnk the status by using
 select a.*,additional_info ,b.ACTUAL_START_DATE,b.RUN_DURATION  from
(
  select  state , job_name,job_action
     from  USER_SCHEDULER_JOBS
     where job_name in ( select job_name from schema_runstat_job_details)
      )A, DBA_SCHEDULER_JOB_RUN_DETAILS B
     where a.job_name=b.job_name
order by RUN_DURATION desc
  
4) check the running jobs
   
      select count(*)       
        from dba_scheduler_jobs
       where job_name in (select job_name from schema_runstat_job_details)
         and state in ('SCHEDULED', 'RUNNING');

--object which are not analysed.
select table_name,last_analyzed From user_tables where trunc(last_analyzed ) <> trunc(sysdate);
select index_name,last_analyzed  from user_indexes
where  trunc(last_analyzed ) <> trunc(sysdate) ;

5) Recall Analysis for the failed object / or for any specific tables and index
if we want call any object/failed object to do the analysis
the below piece of code will help. Change the table name.

begin
      execute immediate 'ALTER SESSION FORCE PARALLEL DDL PARALLEL 5';
      DBMS_STATS.gather_table_stats (
                         ownname      => '&SCHEMA_NAME',
                         tabname      => '&TABLE_NAME' ,
                         method_opt   => 'for all indexed columns size 254',degree      => 5,
                         cascade      => TRUE);
        exception
       when others then
         null;
  end;
/

 

Concern About Oracle Indexes

---------------------------------------------------------------------------------------
Reference Link : http://www.oracle-base.com/articles/misc/efficient-sql-statements.php
--------------------------------------------------------------------------------------
1) Check Your Stats
-------------------
The Cost Based Optimizer (CBO) uses statistics to decide which execution plan to use.
If these statistics are incorrect the decision made by the CBO may be incorrect.
For this reason it is important to make sure that these statistics are refreshed regularly.
2) Why Indexes Aren't Used
------------------------
 * The presence of an index on a column does not guarantee it will be used.
   The following is a small list of factors that will prevent an index from being used.
 * The optimizer decides it would be more efficient not to use the index.
   If your query is returning the majority of the data in a table,
    then a full table scan is probably going to be the most efficient way to access the table.
 * You perform a function on the indexed column i.e. WHERE UPPER(name) = 'JONES'.
   The solution to this is to use a Function-Based Index.
 * You perform mathematical operations on the indexed column i.e. WHERE salary + 1 = 10001
 * You concatenate a column i.e. WHERE firstname || ' ' || lastname = 'JOHN JONES'
 * You do not include the first column of a concatenated index in the WHERE clause of your statement.
   For the index to be used in a partial match, the first column (leading-edge) must be used.

 create table test_index ( name varchar2(10), name1 varchar2(10), name3 varchar2(10))
 create index  ix_test_index on test_index(name, name1)

 create table test_index1 ( name4 varchar2(10), name5 varchar2(10), name6 varchar2(10))
 create index  ix_test_index1 on test_index1(name4, name5)
 select * from test_index where name1='arul' --table access full
 select * from test_index where name1='arul' and name='arul' --ix_test_index
 create index  ix_test_index2 on test_index(name1)

 select * from test_index where name1='arul' --ix_test_index2
 select * from test_index where name1='arul' and name='arul' --ix_test_index

   Index Skip Scanning in Oracle 9i and above allow indexes to be used even when the leading edge is not referenced.
 * The use of 'OR' statements confuses older versions of the Cost Based Optimizer (CBO).
   It will rarely choose to use an index on column referenced using an OR statement. The only way of guaranteeing the use of indexes in these situations is to use an INDEX hint.

3) EXISTS vs. IN
------------------------
The EXISTS function searches for the presence of a single row meeting the stated criteria as opposed to the IN statement which looks for all occurrences.
TABLE1 - 1000 rows
TABLE2 - 1000 rows
(A)
SELECT t1.id
FROM   table1 t1
WHERE  t1.code IN (SELECT t2.code
                   FROM   table2 t2);
(B)
SELECT t1.id
FROM   table1 t1
WHERE  EXISTS (SELECT '1'
               FROM   table2 t2
               WHERE  t2.code = t1.code)
For query A, all rows in TABLE2 will be read for every row in TABLE1.
The effect will be 1,000,000 rows read from items. In the case of query B,
a maximum of 1 row from TABLE2 will be read for each row of TABLE1, thus reducing the processing overhead of the statement.
Rule of thumb:
If the majority of the filtering criteria are in the subquery then the IN variation may be more performant.
If the majority of the filtering criteria are in the top query then the EXISTS variation may be more performant.
I would suggest they you should try both variants and see which works the best.
Note. In later versions of Oracle there is little difference between EXISTS and IN operations.
4) Inequalities
----------------
If a query uses inequalities (item_no > 100) the optimizer must estimate the number of rows returned before
it can decide the best way to retrieve the data. This estimation is prone to errors.
If you are aware of the data and it's distribution you can use optimizer hints to encourage or discourage
full table scans to improve performance.
If an index is being used for a range scan on the column in question, the performance can be improved by substituting >= for >. In this case, item_no > 100 becomes item_no >= 101. In the first case, a full scan of the index will occur. In the second case, Oracle jumps straight to the first index entry with an item_no of 101 and range scans from this point. For large indexes this may significantly reduce the number of blocks read.

FK's :
--------
Try adding new indexes to the system to reduce excessive full table scans. Typically, foreign key columns should be indexed as these are regularly used in join conditions. On occasion it may be necessary to add composite (concatenated) indexes that will only aid individual queries. Remember, excessive indexing can reduce INSERT, UPDATE and DELETE performance.
Table Order
-------------
Driving Tables (RBO Only)
The structure of the FROM and WHERE clauses of DML statements can be tailored to improve the performance of the statement. The rules vary depending on whether the database engine is using the Rule or Cost based optimizer. The situation is further complicated by the fact that the engine may perform a Merge Join or a Nested Loop join to retrieve the data. Despite this, there are a few rules you can use to improve the performance of your SQL.
Oracle processes result sets a table at a time. It starts by retrieving all the data for the first (driving) table. Once this data is retrieved it is used to limit the number of rows processed for subsequent (driven) tables. In the case of multiple table joins, the driving table limits the rows processed for the first driven table. Once processed, this combined set of data is the driving set for the second driven table etc. Roughly translated into English, this means that it is best to process tables that will retrieve a small number of rows first. The optimizer will do this to the best of it's ability regardless of the structure of the DML, but the following factors may help.

Caching Tables
--------------
Queries will execute much faster if the data they reference is already cached. For small frequently used tables performance may be improved by caching tables. Normally, when full table scans occur, the cached data is placed on the Least Recently Used (LRU) end of the buffer cache. This means that it is the first data to be paged out when more buffer space is required. If the table is cached (ALTER TABLE employees CACHE;) the data is placed on the Most Recently Used (MRU) end of the buffer, and so is less likely to be paged out before it is re-queried. Caching tables may alter the CBO's path through the data and should not be used without careful consideration.
Improving Parse Speed by using alias
------------------------------------
Execution plans for SELECT statements are cached by the server, but unless the exact same statement is repeated the stored execution plan details will not be reused. Even differing spaces in the statement will cause this lookup to fail. Use of bind variables allows you to repeatedly use the same statements whilst changing the WHERE clause criteria. Assuming the statement does not have a cached execution plan it must be parsed before execution. The parse phase for statements can be decreased by efficient use of aliasing. If an alias is not present, the engine must resolve which tables own the specified columns. The following is an example.
Bad Statement Good Statement
SELECT first_name,
       last_name,
       country
FROM   employee,
       countries
WHERE  country_id = id
AND    lastname   = 'HALL';
SELECT e.first_name,
       e.last_name,
       c.country
FROM   employee e,
       countries c
WHERE  e.country_id = c.id
AND    e.last_name  = 'HALL';

6) Consider adding columns for index only access
------------------------------------
Sometimes it can be advantageous to include additional columns in an index to increase the chances of index-only access. With index-only access all of the data needed to satisfy the query can be found in the index alone — without having to read data from the table space.
For example, suppose that there is an index on the DEPTNO column of the DEPT table. The following query may use this index:

    SELECT   DEPTNAME
    FROM     DEPT
    WHERE    DEPTNO =  'D01';
The index could be used to access only those columns with a DEPTNO greater than D00, but then the DBMS would need to access the data in the table space to return the DEPTNAME. If you added DEPTNAME to the index, that is, create the index on (DEPTNO, DEPTNAME) then all of the data needed for this query exists in the index and additional I/O to the table space would not need be needed. This technique is sometimes referred to as index overloading.
Of course, this is not always a good idea. You have to take into account whether other queries use the index and how it might negatively impact their performance.
---------------------------------------------------------------------------------------
How to find the redundent index which can be dropped.
reference Link : http://www.dba-oracle.com/t_detecting_duplicate_indexes.htm
--------------------------------------------------------------------------------------
This script will locate all Oracle indexes with duplicate columns.

select /*+ rule */
   a.table_owner,
   a.table_name,
   a.index_owner,
   a.index_name,
   column_name_list,
   column_name_list_dup,
   dup duplicate_indexes,
   i.uniqueness,
   i.partitioned,
   i.leaf_blocks,
   i.distinct_keys,
   i.num_rows,
   i.clustering_factor
from
  (
   select
      table_owner,
      table_name,
      index_owner,
      index_name,
      column_name_list_dup,
      dup,
      max(dup) OVER
       (partition by table_owner, table_name, index_name) dup_mx
   from
      (
       select
          table_owner,
          table_name,
          index_owner,
          index_name,
          substr(SYS_CONNECT_BY_PATH(column_name, ','),2)  
          column_name_list_dup,
          dup
       from
          (
          select
            index_owner,
            index_name,
            table_owner,
            table_name,
            column_name,
            count(1) OVER
             (partition by
                 index_owner,
                 index_name) cnt,
             ROW_NUMBER () OVER
               (partition by
                  index_owner,
                  index_name
                order by column_position) as seq,
             count(1) OVER
               (partition by
                  table_owner,
                  table_name,
                  column_name,
                  column_position) as dup
   from
      sys.dba_ind_columns
   where
      index_owner  in ('&OWNER'))
where
   dup!=1
start with seq=1
connect by prior seq+1=seq
and prior index_owner=index_owner
and prior index_name=index_name
)) a,
(
select
   table_owner,
   table_name,
   index_owner,
   index_name,
   substr(SYS_CONNECT_BY_PATH(column_name, ','),2) column_name_list
from
(
select index_owner, index_name, table_owner, table_name, column_name,
count(1) OVER ( partition by index_owner, index_name) cnt,
ROW_NUMBER () OVER ( partition by index_owner, index_name order by column_position) as seq
from sys.dba_ind_columns
where index_owner in ('&OWNER' ))
where seq=cnt
start with seq=1
connect by prior seq+1=seq
and prior index_owner=index_owner
and prior index_name=index_name
) b, dba_indexes i
where
    a.dup=a.dup_mx
and a.index_owner=b.index_owner
and a.index_name=b.index_name
and a.index_owner=i.owner
and a.index_name=i.index_name
order by
   a.table_owner, a.table_name, column_name_list_dup;
---------------------------
Another query :
reference : http://www.orafaq.com/node/926
---------------------------
SELECT
   /*+ RULE */
   tab_owner.name owner, t.name table_name,
   o1.name || '(' || DECODE(bitand(i1.property, 1), 0, 'N', 1, 'U', '*') || ')' included_index_name ,
   o2.name || '(' || DECODE(bitand(i2.property, 1), 0, 'N', 1, 'U', '*') || ')' including_index_name
FROM  sys.USER$ tab_owner, sys.OBJ$ t, sys.IND$ i1, sys.OBJ$ o1, sys.IND$ i2, sys.OBJ$ o2
WHERE i1.bo# = i2.bo# AND i1.obj# <> i2.obj# AND i2.cols >= i1.cols AND i1.cols > 0 AND
   i1.cols = ( SELECT /*+ ORDERED */ COUNT(1) FROM sys.ICOL$ cc1, sys.icol$ cc2
               WHERE cc2.obj# = i2.obj# AND cc1.obj# = i1.obj# AND
                     cc2.pos# = cc1.pos# AND cc2.COL# = cc1.COL#) AND
   i1.obj# = o1.obj# AND i2.obj# = o2.obj# AND t.obj# = i1.bo# AND
   t.owner# = tab_owner.USER# AND tab_owner.name LIKE '%'
ORDER BY 1, 2
Rule to drop the index
-----------------------
If 2 indexes ( I1 and I2 ) exist for a table and
   the number of columns in Index I1 is less or equal to the number of column in index I2 and
   index I1 has the same columns in the same order as leading columns of index I2
Then
   If index I1 is UNIQUE then
      If index I2 is used to support Foregh Key or for Index Overload then
         Do Nothing
      Else
         Index I2 can be DROPPED
      End If
   Else
      Index I1 can be DROPPED
   End If
End If

----------------------------------------
Displays a list of non-indexes FKs
----------------------------------------
SELECT t.table_name,
       c.constraint_name,
       c.table_name table2,
       acc.column_name
FROM   user_constraints t,
       user_constraints c,
       user_cons_columns acc
WHERE  c.r_constraint_name = t.constraint_name
AND    c.table_name        = acc.table_name
AND    c.constraint_name   = acc.constraint_name

AND    NOT EXISTS (SELECT '1'
                   FROM  user_ind_columns aid
                   WHERE aid.table_name  = acc.table_name
                   AND   aid.column_name = acc.column_name
                  )
ORDER BY c.table_name;

---------------------------------------------------------------------------------------
How to monitor the index usability
--------------------------------------------------------------------------------------
SET PAGESIZE 0
SET FEEDBACK OFF
SET VERIFY OFF
SPOOL temp.sql
SELECT 'ALTER INDEX "' || i.owner || '"."' || i.index_name || '" MONITORING USAGE;'
FROM   dba_indexes i
WHERE  owner      = UPPER('&1')
AND    table_name = DECODE(UPPER('&2'), 'ALL', table_name, UPPER('&2'));
SPOOL OFF
SET PAGESIZE 18
SET FEEDBACK ON
@temp.sql

status :
----------
SET VERIFY OFF
SELECT table_name,
       index_name,
       monitoring
FROM   v$object_usage
WHERE  table_name = UPPER('&1')
AND    index_name = DECODE(UPPER('&2'), 'ALL', index_name, UPPER('&2'))

usgae
-------
SET VERIFY OFF
SET LINESIZE 200
SELECT table_name,
       index_name,
       used,
       start_monitoring,
       end_monitoring
FROM   v$object_usage
WHERE  table_name = UPPER('&1')
AND    index_name = DECODE(UPPER('&2'), 'ALL'

Monitor off;
-----------------
SET PAGESIZE 0
SET FEEDBACK OFF
SET VERIFY OFF
SPOOL temp.sql
SELECT 'ALTER INDEX "' || i.owner || '"."' || i.index_name || '" NOMONITORING USAGE;'
FROM   dba_indexes i
WHERE  owner      = UPPER('&1')
AND    table_name = DECODE(UPPER('&2'), 'ALL', table_name, UPPER('&2'));
SPOOL OFF
SET PAGESIZE 18
SET FEEDBACK ON
@temp.sql

 

How to load data faster in Oracle sqlldr.

Pre-process Tips : Below tips can be very helpful when we are doing the bulk data upload using the data files.

Some of tips can be ignored when we are doing the small amount of data or the destination table is having less records and No of index/foreign keys are less.
 

1)  Initiate the data load(sqlldr ) on the server rather than executing it from desktop. This will make the load much faster.

2) Create Temporary table for load purpose and  load to temp table with sqlldr on parallel and direct option 

2.1) create the temp table for each file

               *:  read header line from data file -- which gives the columns are present in the data file.
              comment :  head 5 filename.csv
             -- copy the column and do the selct in sql plus

           -- copy the same column order into any control file
           -- change the infile , bad filem, discard file to the same location of where ur dat file present
           -- change the table name
          --any timestamp column should be modified like below.

              --NULLIF UPDATEDTTM=BLANKS "to_timestamp(:UPDATEDTTM,'RRRR-MM-DD HH24:MI:SS.FF')", 

create table TEST_LOAD
as
select 
* from TEST where 1=2;
Note : Instead of loading the Data into the destination table , We will suggest to load it to the intermediary table for the large loads.  
       : this will help to increase the performance of multiple file for a same table , so this load can be run parrallel
       : this will help to validate the records before inserting into the actual tables      

2.2) create ctl file for each data file or use the same table for multiple files with append Option.    

2.3) Load Data

open multiple sqlplus session and call the sqlldr.
sqlldr schema/password@connection_string TEST_DATA.ctl ERRORS=100 parallel=true

3) Change destination table to No-logging mode.

             alter table TEST_LOAD NOLOGGING ;
             Note : It bypasses the writing of the redo log, significantly improving performance

4) Force the session to use  parallel DDL/DML.

Parallel session can be calculated by using
select * from v$parameter
PARALLEL_DEGREE_POLICY
select * from v$parameter where name like '%cpu%'
select * from v$parameter where name like 'para%'
select * from v$parameter where name like 'para%' or name like '%cpu%'
For a single instance, DOP = PARALLEL_THREADS_PER_CPU x CPU_COUNT
For an Oracle RAC configuration, DOP = PARALLEL_THREADS_PER_CPU x CPU_COUNT x INSTANCE_COUNT
       ALTER SESSION FORCE PARALLEL DDL PARALLEL 8;
       ALTER SESSION FORCE PARALLEL DML PARALLEL 8;
       Note : this will force the DDL/DML operation to run in parallel.

5) Drop All Index and disable foreign Key on the table.

To avoid the tm locks on foreign key and index and child tables. Take the Index creation script before dropping it.
Note : If its data load then the above is enough.
In case of delete and restore ( like colombian template load table vfminstr)
All child table fks which is referring the test table should be disabled
and delete the child table record manually and enable fk after the delete and data load.

 

7)  insert data with append hint


insert /*+ append */ into TEST
select * from TEST_DATA ;
Commit;
Note : this will directly insert the record above High-level water mark.

8) enable constraint / recreate Index which are dropped in step 5

     Note : create missing fk index which makes the constraint enable much faster
     Enable all disabled constraints
     Drop the index which is created temporally for faster constraints enable.
     Re create dropped index

9) alter table to logging mode


10) Drop Temp / external table


11) Do the table analysis