注册
日常慢的问题排查思路分享1
技术分享/ 文章详情 /

日常慢的问题排查思路分享1

tdj305 2024/11/29 472 1 0

最近在多个项目中遇到系统卡顿的问题,总结多次问题处理的结果,做个简单的分享。
问题现象
应用报网络通信异常或连接超时。
处理方法
1、 慢SQL处理
(1) 生产环境,通过

select sf_get_session_sql(sess_id) full_sql,datediff(ss,last_send_time,current_timespamp()) time_used,* from v$sessions where state=’ACTIVE’ order by 2 desc

找出慢SQL并导出到excel中,查看当前SQL计划是否正常,如果不正常针对慢SQL进行优化(注意上班时间禁止操作);如果SQL执行正常,大部分情况是内存中的计划和当前计划不一样,有可能是统计信息不准导致,可以通过inject绑定计划的方式绕过(谨慎收集统计信息,只能在非上班时间做)。
(2) 通过vleng_exec_sqls或者VSQL_HISTORY视图查看。同样先查看当前计划,再查看内存中的计划。
(3) 查看内存中的计划。
A、 通过trace文件查看
–先确认sql对应的执行计划缓存号cache_item
select cache_item,sqlstr,* from vcachepln where sqlstr like '%SQL语句片段%' ; 然后通过trace文件进行分析 --假定cache_item=123456 Alter session set events 'immediate trace name plndump,level 123456'; 然后到数据库的trace目录下(一般在../DAMENG/trace下面),具体查看方法这里省略。 如果看到计划和现在不一样,可以清理单条SQL的计划, --假定需清理的缓存号为123456' sp_clear_plan_cache('123456'); B、 通过系统包查看 通过系统自带的DBMS_SQLTUNE包查看,使用包内的过程和函数之前,如果还未创建过系统包,请先调用系统过程创建系统包。SP_CREATE_SYSTEM_PACKAGES (1,'DBMS_SQLTUNE'); 另外需要ENABLE_MONITOR和MONITOR_SQL_EXEC 均设置为 1。 然后执行SELECT DBMS_SQLTUNE.REPORT_SQL_MONITOR(SQL_EXEC_ID=>123) 其中SQL_EXEC_ID可通过视图VSQLTEXT、VSESSIONS、VSQL_HISTORY、V$LONG_EXEC_SQLS等视图中查询。
2、 连接池配置问题
应用连接池配置的时候,都有初始值、最小值、最大值,现在的业务系统并发越来越大,当初始值太小时,并发上来后就会新建连接,而新建连接耗时比较大,这样就导致部分SQL执行很快,但是通过系统视图监控时发现时耗时较长。特别是读写分离情况下,会执行下面这条SQL:

select distinct mailIni.mal_inst_name, mailIni.mal_INST_HOST, mailIni.mal_INST_PORT, archIni.arch_status from v$arch_status archIni left join (select * from V$DM_MAL_INI) mailIni on archIni.arch_dest = mailIni.mal_inst_name left join V$MAL_LINK_STATUS on CTL_LINK_STATUS  = 'CONNECTED' AND DATA_LINK_STATUS = 'CONNECTED' where archIni.arch_type in ('TIMELY', 'REALTIME')

这样在分析问题的时候就会误导我们。这时候需要到dem(尽量每个项目都部署)中查看会话信息,查看是否存在会话增加比较明显,如果会话增加明显,说明就是连接池配置的问题,需要将最小值和初始化设置大一点。
image.png
比如这种情况,可以把初始值和最小值都设置为50。

经验分享
1、 分页慢
最近遇到SQL执行很快10ms以内,结果集也就几条,可是加上limit 0,20或者其他分页的时候巨慢,1分钟出不来结果,多方分析后发现是TOP_ORDER_OPT_FLAG=1导致,这个参数是默认参数,大部分都时1,下次遇到类似问题时优先排查这个。Bug系统已提交bug,后面可以参考下修改进去。
image.png

2、 Hash导致慢
针对多表关联,当关联列具有很好的过滤性时,尽量走nest loop index join,避免走hash join,因为hash join在并发情况下,资源消耗比较大,加上数据量大,从而导致查询异常慢。
如下面这条SQL:

select t.*, messages_mobile_config.istop from (select test1.*, row_number () over ( partition by typeguid order by sendtime desc) rn from test1 where 1=1 and test1.targetuserid = ? and test1. status !=9) t 
left join test2 on t.typeguid = test2 .typeguid and t.targetuserid = test2 .userid where rn = 1

默认走的hash join,导致查询异常慢,通过inject,禁用hash_join后正常。Hint:enable_hash_join(0)。

评论
后发表回复

作者

文章

阅读量

获赞

扫一扫
联系客服