案例:ERP系统中项目数量非常多,在项目管理模块,有个WEB界面是用于调整任务信息的。克隆环境后,用户发现该功能的访问速度和正式环境有明显差异。经询问各方面人员(包括用户和实施顾问),都说没有做过任何特殊变动。
任何一名实施顾问,首要的经验就是要学会明确自己和普通用户的不同。一种业务,或者一个功能,绝对不能完全站在用户的立场来看待问题。如果用户说没有做过更改,那是从功能使用角度来讲的,作为系统和功能之间起到桥梁作用的ERP实施人员,还应当关注系统本身的变化。首先,克隆本身就是一种变化,比如硬件平台的变化、文件路径的变化、访问方式的变化,甚至系统参数(数据库或应用)也可能变化。任何一种变化,都可能导致用户体验的不同。一个新克隆的系统,第一次访问就发现速度变慢(或者变快),实施顾问应当事先就预料到各种可能的情况。从我的经验来看,没有做过变动的可能性非常小,那就通过一些简单的技术手段来找到这种变化。
先对该功能启用诊断后发现,有一段执行任务列表查询的SQL存在明显的性能问题。
克隆环境检查该SQL的执行计划:
SQL> set linesize 1000 SQL> set pagesize 1000 SQL> explain plan for SELECT * 2 FROM (SELECT * FROM pa_task_progress_v) qrslt 3 WHERE (task_manager_person_id = 126) 4 ORDER BY project_name ASC, 5 task_name ASC 6 ; Explained. SQL> select * from table(dbms_xplan.display); PLAN_TABLE_OUTPUT ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | ---------------------------------------------------------------------------------------------------- …… |* 14 | HASH JOIN | | 1 | 239 | 5274 | |* 15 | TABLE ACCESS BY INDEX ROWID | PA_PROJ_ELEMENT_VERSIONS | 2 | 86 | 3 | | 16 | NESTED LOOPS | | 381 | 84201 | 5253 | |* 17 | HASH JOIN | | 252 | 44856 | 4497 | |* 18 | TABLE ACCESS BY INDEX ROWID| PA_PROJ_ELEMENTS | 445 | 65860 | 4492 | |* 19 | INDEX RANGE SCAN | PA_PROJ_ELEMENTS_N1 | 81751 | | 357 | |* 20 | TABLE ACCESS FULL | PA_TASK_TYPES | 9 | 270 | 4 | |* 21 | INDEX RANGE SCAN | PA_PROJ_ELEMENT_VERSIONS_N1 | 2 | | 2 | |* 22 | TABLE ACCESS FULL | PA_PROJ_ELEM_VER_STRUCTURE | 1732 | 31176 | 20 | |* 23 | TABLE ACCESS BY INDEX ROWID | PA_PROJ_ELEM_VER_SCHEDULE | 1 | 34 | 2 | |* 24 | INDEX UNIQUE SCAN | PA_PROJ_ELEM_VER_SCHEDULE_U2 | 1 | | 1 | …… ----------------------------------------------------------------------------------------------------
再在正式环境中检查同一句SQL的执行计划:
PLAN_TABLE_OUTPUT ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost | ---------------------------------------------------------------------------------------------------- …… |* 14 | HASH JOIN | | 1 | 239 | 3793 | |* 15 | TABLE ACCESS BY INDEX ROWID| PA_PROJ_ELEMENT_VERSIONS | 2 | 86 | 3 | | 16 | NESTED LOOPS | | 393 | 86853 | 3787 | |* 17 | HASH JOIN | | 253 | 45034 | 3028 | |* 18 | TABLE ACCESS FULL | PA_PROJ_ELEMENTS | 446 | 66008 | 3025 | |* 19 | TABLE ACCESS FULL | PA_TASK_TYPES | 9 | 270 | 2 | |* 20 | INDEX RANGE SCAN | PA_PROJ_ELEMENT_VERSIONS_N1 | 2 | | 2 | |* 21 | TABLE ACCESS FULL | PA_PROJ_ELEM_VER_STRUCTURE | 1883 | 33894 | 5 | |* 22 | TABLE ACCESS BY INDEX ROWID | PA_PROJ_ELEM_VER_SCHEDULE | 1 | 35 | 2 | |* 23 | INDEX UNIQUE SCAN | PA_PROJ_ELEM_VER_SCHEDULE_U2 | 1 | | 1 | …… ----------------------------------------------------------------------------------------------------
从两者对比上看,可以发现正式环境中该SQL并没有用到PA_PROJ_ELEMENTS的索引,基本上可以确定两个环境同一个功能访问速度不同的原因。同样的语句,在克隆环境和正式环境中的执行计划不一样。两个环境分别重新收集统计信息后,依旧如此。
从用户角度看,问题出在系统方面;从实施顾问角度看,此类系统问题应当寻求技术人员尤其是DBA的帮助,为什么会出现这种差异。经过进一步的诊断,发现正式环境中 db_file_multiblock_read_count 参数被设置为100,而克隆环境中该参数被设置为8。在克隆环境中尝试调整该值,可以确定正是该参数导致了执行计划的不同。
这里不对db_file_multiblock_read_count做探讨,这应该交给专业的性能调优人员去分析。回到开始,我们在发现问题后询问各方人员,为什么都回答没有做任何特殊变动呢?这其实是个非常有趣的话题,我想,最大的问题还是出在“习惯”二字上面。做了几十上百次同样的操作,当某一天发现这种方式出现问题时,我们条件反射的把这种习惯性操作排除在外,而把问题原因归咎于某些未知的可能性上面。
一个有经验的实施人员,和一个没有经验的实施人员,其生产力差别可见一斑。
