第一步:执行会话统计,找到需要优化的sql

 
 --注意:v$sql 与v$sqlarea 有很大的区别就在与,v$sqlarea 是根据sqltext进行分类的,那就会导致不同用户执行了同一个sql,被统计在了一起,所以一定要使用v$sql.
 
 ---查询每个进程执行的对应的sql,以及可以干掉该sql的sql语句
--spid     oracle 程序进程号
--executions 代表执行次数
--EXACT_MATCHING_SIGNATURE                                              没有删除常量时,算出来的hash值   --常量就是where后面这些字段等于的值。  
--FORCE_MATCHING_SIGNATURE 代表可以共享coursor(即可以实现软件解析)。   删除了常量时,算出来的hash值。   如果SQL中有绑定变量,那就是没有常量,所以force_matching_signature就会与exact_matching_signature一样的生成标准 。所以就可以说是实现了绑定变量。
--version_count 当有大量的version_count,说明虽然SQL语句相同,但是Oracle 发现因为某些原因不可重用这些SQL,此时,再去查看 c.* 中的值,找到为 Y 的列,就是sql不能重用的原因
--cpu_time 和elapsed_time 单位都是ms。 每次执行的时间,需要处理,执行次数
--alterxxxxxx 这个是删除sql的语法 (只能在sql/plus 中执行)
---machine 代表是谁发起的这个sql
---order by 为了根据谁最消耗cpu进行排序
select d.sql_text,d.sql_fulltext,a.spid,a.pid,b.sql_id,d.executions,e.version_count,d.EXACT_MATCHING_SIGNATURE,d.FORCE_MATCHING_SIGNATURE,b.username,b.MACHINE,d.cpu_time,d.ELAPSED_TIME,c.*,b.sid,b.serial#, \'alter system kill session\'\'\'||b.SID||\',\'||b.serial#||\'\'\';\'
from v$sql d,v$process a, v$session b,v$sql_shared_cursor c,v$sqlarea e
where a.addr = b.paddr
and b.SQL_ID=d.SQL_ID
and c.sql_id=d.sql_id
and  e.sql_id=d.sql_id
order by d.cpu_time desc

第二步:拿到需要优化的sql,在测试脚本中,运行

-- Created on 2019-03-07 by ADMINISTRATOR 
declare 
  -- Local variables here
     my_task_name VARCHAR2(30);

begin
    
--更新表的统计信息
--dbms_stats.gather_table_stats(\'pmsuser\',\'PMS_PRODUCT_INFO\',cascade=>true); 


    --执行

 my_task_name :=DBMS_SQLTUNE.CREATE_TUNING_TASK( 
                                               --  sql_id => \'7f34mcwy3506w\',
                                                                                             sql_text=> \'select t.id, t.store_name, prov.name    storeProv, city.name    storeCity, area.name    storeArea, t.store_addr storeAddr from pmsuser.pms_firm_store_info t left join pmsuser.sys_area prov on t.STORE_PROV = prov.id left join pmsuser.sys_area city on t.STORE_CITY = city.id left join pmsuser.sys_area area on t.STORE_AREA = area.id where t.status = \'\'100002\'\' and exists (select 1 from pmsuser.pms_r_saler_store a left join pmsuser.pms_r_product_store b on a.str_id = b.obj_id left join pmsuser.pms_product_affiliated_core c on b.version_no = c.version_no left join pmsuser.pms_product_info d on c.product_no = d.product_no where t.id = a.str_id and a.is_del = \'\'100002\'\' and b.status = \'\'100017\'\' and c.is_del = \'\'100017\'\' and d.status = \'\'100017\'\' and a.firm_id = \'\'500007001\'\' and a.user_id = \'\'ZHXJDY0705\'\' and d.product_type = \'\'200001\'\')\',
                                                                                                 scope => \'COMPREHENSIVE\',time_limit => 60,
                                                 task_name => \'test_sql_tuning_task2\',
                                                                                                 description => \'Task to tune a query\');




DBMS_SQLTUNE.EXECUTE_TUNING_TASK(task_name => \'test_sql_tuning_task2\'); 
    /*


    --查看结果
select dbms_sqltune.report_tuning_task(\\'test_falist_tuning_task1\\') from dual;


--删除执行结果
dbms_sqltune.drop_tuning_task(\'test_sql_tuning_task2\');
*/







/*
--至今未研究明白
 my_task_name :=DBMS_ADVISOR.QUICK_TUNE(DBMS_ADVISOR.SQLACCESS_ADVISOR,
                            v_task_name => \'test_sql_tuning_task2\',
                            v_sql_stmt =>\'SELECT ad.PRODUCT_NO, ur.url CHANNEL_URL,ad.VALID_DAYS QR_CODE_DATE, ad.SELF_URL H5_CHANNEL_URL, ad.PLACE_NAME CHANNEL_NAME, ad.BUSI_CREDIT_TYPE TYPE_OF_SERVICE, ad.PLACE_NO CHANNEL_NO, (CASE WHEN f.LIB_DIRECTORY IS NOT NULL THEN f.LIB_DIRECTORY || f.LIB_NAME || \'\'.\'\' || f.LIB_EXT_NAME ELSE NULL END) CHANNEL_LOGO, ad.PRODUCT_REMARK PRODUCT_INTRODUCTION, ad.APPLY_REMARK APPLICATION_DESCRIPTION, ad.SHOW_WEIGHT DISPLAY_WEIGHT, ad.PROPOSER_NUM APPLICATION_NUMBER, ad.PRODUCT_LABEL PRODUCT_TAG FROM PMSUSER.PMS_PRODUCT_AFFILIATED_ADVERTI ad LEFT JOIN ( SELECT PRODUCT_NO, listagg(URL, \'\'|\'\') WITHIN GROUP (ORDER BY PRODUCT_NO) url FROM PMSUSER.PMS_PRODUCT_ADVERTIS_URL GROUP BY PRODUCT_NO ) ur ON ur.PRODUCT_NO = ad.PRODUCT_NO LEFT JOIN PMSUSER.PMS_LIBRARY_INFO f ON f.ID = ad.FILE_ID WHERE 1 = 1\'
                            );
 


*/


-- Test statements here 

end;

运行结束后,会生成一份报告,直接运行

select dbms_sqltune.report_tuning_task(\\'test_falist_tuning_task1\\') from dual;

就可以得到结果。根据报告中提及到的优化建议。进行优化

第三步:优化建议,就一定是最好的吗。当然不是,为了保证优化的效果。需要对oracle 给出的建议进行一一尝试。

  如果遇到复合索引,建议长度为2,那么该那两个进行组合呢?首先,将唯一性最高的列,作为第一个。第二个列怎么确定呢

如下:

SELECT COUNT( PRODUCT_NO || status) ,COUNT( DISTINCT PRODUCT_NO || status) FROM pmsuser.pms_product_info

这类的方式来确定,这个两个值越接近,说明其唯一性就越高,那么这两个值来组合最好。

第四步:当然是验证自己创建的索引的效果

赠送创建/删除索引的语句:

drop index PMSUSER.IDX_rss_userid_isdel;             
            
         
create index PMSUSER.IDX_rss_userid_isdel on
    PMSUSER.PMS_R_SALER_STORE("USER_ID","FIRM_ID");

 

版权声明:本文为augus007原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/augus007/articles/10521545.html