搞過Oracle的應該都知道Oracle的In不能超過1000如果超過1000會直接報錯。這里分享幾個方案來解決這個問題。
- 使用 in + union all 的子查詢,這種方法對原有代碼改動最小。例如:
1 select i.* 2 from table1 i 3 where field1 in ( 4 select '1' from dual 5 union all 6 select '2' from dual 7 union all 8 select '3' from dual 9 )
Mybatis中可以這么寫。PS:最好別用#{},經嘗試druid解析占位符過多的時候會報錯。我的druid版本是:1.0.11
<if test="@Ognl@isNotEmpty(codeList)"> and i.code in <foreach item="code" index="index" collection="codeList" open="(" separator=" union all " close=")"> select '${code}' from dual </foreach> </if>
- 跟上面方法類似,但把子查詢用 with a as封裝起來。這種方式如果in條件在很多地方用到,性能會比較高。例如:
1 with t as ( 2 select '1' as code from dual 3 union all 4 select '2' as code from dual 5 ) 6 select i.* 7 from table1 i 8 where i.code in ( 9 select t.code from t 10 )
- 使用 a IN (1,2,...,999) or a in (1000,1001,...1999) or ....這種方式性能相對不高。
- 在Java中按1000分批查詢,再把結果加起來,這種方式稍復雜,而且查詢次數過多,對原代碼改動較大,最好讓測試測下超過1000的場景。
- 新建臨時表,再查詢之前把數據都插入到表里,然后再查詢。這種方式要控制好並發的場景,不然容易出錯。