近期项目上反馈每天上午系统都比较卡顿,查看期间的数据库慢SQL记录,其中95%以上为1条UPDATE语句,执行时间几秒到几十秒不等。该SQL包含like条件字段的过滤性很好,其它字段基本没有过滤性,表数据量只有十几万。
通过客户端EXPLAIN查看执行计划正常,走过滤字段的组合索引,检查统计信息刚收集过。刚开始以为是执行计划缓存没清理,清理了几次缓存,执行仍然比较慢。通过PLNDUMP导出实际执行计划发现走的是全表扫,实际执行计划如下:
查看会话连接情况,应用使用的驱动版本比数据库版本低,联系项目更换应用驱动后问题仍然没有解决。后来想到是不是和LIKE优化参数LIKE_OPT_FLAG有关,修改LIKE_OPT_FLAG=0,等待连接池的会话重新生成后,已经看不到此慢SQL。导出执行计划也走了索引,修改参数后的执行计划如下:
在项目生产环境只确定了是由LIKE优化参数影响的,但是还不清楚具体是怎么影响。就在自己本地模拟生产数据分布情况,通过java程序测试在传参情况下和生产现象一致,开启LIKE优化走全表扫,关闭后走索引定位。
当LIKE_OPT_FLAG取默认值127时,通过AUTOTRACE跟踪执行计划,会将LIKE转化为ITEMID LIKE exp_param(no:1) AND ITEMID >= var3 AND ITEMID < var4,此时对于结果行数的估算与实际偏差很大,占用总表一半的数据走了全表扫。
当关闭LIKE优化时,LIKE条件为ITEMID LIKE exp_param(no:1),结果行数的估算与实际偏差较低,走索引定位。
后来又想到行数估算也收到BEXP_CALC_ST_FLAG参数的影响,当LIKE_OPT_FLAG取默认值127、BEXP_CALC_ST_FLAG取默认值128(包含对LIKE过滤条件进行调整),通过AUTOTRACE跟踪执行计划如下:
当LIKE_OPT_FLAG取默认值127、BEXP_CALC_ST_FLAG取值0时,结果行数估算与实际偏差不大,走索引定位。
当LIKE_OPT_FLAG取值0、BEXP_CALC_ST_FLAG取值0时,结果行数估算与实际偏差也不大,走索引定位。
在某些场景下LIKE优化可能会导致行数估算错误,导致执行计划不是最优的,在生产中应当注意LIKE_OPT_FLAG和BEXP_CALC_ST_FLAG对LIKE行数估算的影响。同时EXPLAIN查看的只是预估的执行计划,即使传入参数仍然不会实际执行,可能和实际情况有区别。
文章
阅读量
获赞
