Monday, November 24, 2014

Oracle Tuning a Query -table with 25 million Record

Am Having the transaction table which will grow daily and now  row count is around 25 million.

This is my query taking more time  and cost. Its due to order by in the computation field(TOTAL_WEIGHT)

SELECT   PPS_ID,TOTAL_WEIGHT from
                      (SELECT PPS_ID,TOTAL_WEIGHT
                        FROM (SELECT pps_id,round(((( 60 * name_pct_match / 100) + prs_weight + year_weight + dt_weight)/
                              90) * 100) total_weight
                FROM (SELECT pps_id,
                       round(func_compare_name( 'FRANCIS JOHN ROCH',upper(name_en),' ',60)) name_pct_match,
                       decode(prs_nationality_id, 99, 15, 0) prs_weight,
                       10 mother_weight,
                       100 total_attrib_weight,
                case when to_number(to_char(birth_date, 'yyyy')) = 1986 then 5 else 0 end year_weight,
                case when to_char(to_date('12-JAN-86','DD-MON-RRRR'), 'dd') = to_char(birth_date, 'dd')
                  and to_char(to_date('12-JAN-86','DD-MON-RRRR'), 'mm') = to_char(birth_date, 'mm') then 10
                     when to_date('12-JAN-86','DD-MON-RRRR') between birth_date-6 and birth_date+6 then 8
                     when to_date('12-JAN-86','DD-MON-RRRR') between birth_date-28 and birth_date+28 then 5
                     when to_date('12-JAN-86','DD-MON-RRRR') between birth_date-90 and birth_date+90 then 3
                else 0
                end dt_weight
                  FROM individual_profile
                 WHERE birth_date = '12-JAN-86' 
                 AND IS_ACTIVE = 1
                   AND gender_id = 1 
                   AND round(func_compare_name('FRANCIS JOHN ROCH',upper(name_en),' ',60)) > 20
                   ))
                  WHERE TOTAL_WEIGHT >= 100 
                  order by total_weight desc)
                  where rownum <= 10
Till oracle 11g there is no way to solve order by issue. In oracle 12c oracle  introduced TOP LIMIT concept to reduce this burden. In my case i cant use this since my DB is oracle 11g. so i did following steps to make this query performing
Step -1: Initially i thought to made my fetch fast. So i partitioned the table by birth_date and subpartitioned by gender_id. So now my fettch became fast.
Step -2: partitioned the table bith_date year wise as range partition  and gender wise as list partition.
Step-3:  Now i made the fetch faster. my query is used by many users at a time. So i want to think about CPU utilization also. After taking explain plan i found  bytes is high and cost somewhat reduced
Step-4: Now i tried different indexes to reduce the cost and bytes. but nothing helped as order by  is used.
step-5 : Finally i decided to make my query to run in parallel.
step-6: Oracle 11g has option of parallel(auto) which tell the optimizer to run in parallel based on user
step -7: SELECT  /*+ parallel(auto) */  PPS_ID,TOTAL_WEIGHT from 
step-8: added parallel hint which brought down cost and bytes. now query is performing well
Note: This parallel wont take indexes used in the table.It  will ran in parallel way.
         


No comments:

Post a Comment