Oracle大in慢查询优化

来源:这里教程网 时间:2026-03-03 22:41:06 作者:

1、某客户业务模块大in导致慢SQL: 2.从现场获取到慢SQL信息:1)表数据量不大,只有几十万2)表更新较为频繁,从另外系统同步过来,实际上变更并不频繁,只有少量的updates 3.AWR报告无明显异常: 4.业务逻辑分析:1)原始SQL:SELECT A.FId "id", A.fnumber "number", A.fctrlstrategy "ctrlStrategy", A.fmasterid "masterid", A.fstatus "status", A.fcreateorgid "createOrg.id"FROM xx_Material A WHERE A.FId IN (SELECT COLUMN_VALUE FROM UDT_INTTABLE(?)) AND (A.fbitindex IN (SELECT COLUMN_VALUE FROM UDT_INTTABLE(?)) OR (A.fcreateorgid = ? AND A.fctrlstrategy = ? OR A.fstatus = ? AND A.fctrlstrategy = ?) OR A.fctrlstrategy = ? AND (A.fcreateorgid = ? OR A.fstatus = ? AND A.fcreateorgid=100000)) 2)SQL分析UDT_INTTABLE是一个自定义类型,用于封装大in,规避Oracle in超过1000报错问题,涉及代码:        CREATE OR REPLACE TYPE "UDT_INTTABLE" AS TABLE OF number(19)使用IN (SELECT COLUMN_VALUE FROM UDT_INTTABLE(?)) 将大量in封装后,整个执行计划为FTS(未截图) 5.执行计划分析:由于FID是主键,整个表几十W记录,而in只有上千个,从COST成本预估分析,正确的执行计划应该使用in..list(iterator) NL ,类似如下: optimizer预计计算有误,执行计划FTS有问题 5.优化方案:1)考虑使用table函数代替子查询( SELECT COLUMN_VALUE FROM UDT_INTTABLE(?))改写,如: select * from t_big where id in (select * from table(UDT_INTTABLE(1,2,3,4,5,6,7,8,9,10,100))),执行计划如上。 2)将in转换为临时表(依赖程序框架实现),in list iterator转换为NL JOIN

相关推荐