生产有个功能是上传一个 excel 来进行批量数据操作,excel 里面有三列数据,构建出来的查询大概如下:
select * from t_test t where (t.col1, t.col2, t.col3) in (
(:1, :2, :3),
(:4, :5, :6)
)
IN 子句的长度取决于上传的 excel 里的行数,每一行对应一个 元组。
由于没有限制 excel 里最大行数,导致构建出来的 SQL 有1万多个绑定变量,然后这个 SQL 一直处于解析中,阻塞了这个表上的其他操作(当时主要是插入操作)。(DBA 联系厂商分析给出的结论)
之前一直以为 IN 的列表不能超过 1000,那么生产为什么没有报错,当时拿了那个引发问题的 excel 文件在测试环境复现,是可以正常执行完成的。
DBA 的解释是 11g 里不会报错,19c 开始会报错。DBA 另外提到 IN 列表过长的执行效率是不高的,IN 列表每多一行,执行计划 UNION ALL 下也多一行:
今天重新提起这个,有同事写了个 SQL 在本地验证是报错的:
select * from t_test t where t.col1 in (1, 2, 3, ..., 1001);
为啥当时测试环境复现通过,这个为啥报错?必须搞清楚了。