Oracle中IN的集合不能大于1000条的处理方法

最近用Oracle开发,发现Oracle跟Mysql还是有很多细微之处不一样,例如本文记录的IN的内容不能大于1000条的问题,我在mysql好像没有遇到过,之前只听说IN语句会影响性能。

好的,废话不多说,遇到这个问题,我找了几种方法处理:

一、拆分SQL

最简单的方法,将总集合拆分为每999个为一集合,每个集合单独一条SQL查询,将每个查询结果用UNION ALL合并起来。

SELECT * FROM T_USER WHERE USER_ID IN ('114664882678267904', '114457962503733248')
UNION ALL
SELECT * FROM T_USER WHERE USER_ID IN ('114658384933814272')

用UNION ALL比UNION快,UNION不允许重复,会对结果去重且排序。

二、正则表达式截取成结果集

拆分SQL的方法是能得到想要的结果,但这样处理会有几个问题,首先IN的性能不好,其次SQL的优雅性没了,如果查询结果还要加查询条件,排序这些,还要在外面再套一层select语句。有没有更好的处理方法呢?刚好看到一篇文章说REGEXP_SUBSTR函数的处理方案,惊了,还能这么写。

REGEXP_SUBSTR —— 字符串正则表达式处理函数

REGEXP_REPLACE(source_char, pattern [, replace_string [, position [, occurrence [, match_parameter ] ] ] ] )

        source_char     :需要进行处理的字符串

        pattern    :进行匹配的正则表达式

        replace_string   :替换的字符

        position :从第几个字符开始正则表达式匹配。(默认为1)

        occurrence   :标识第几个匹配组

        match_parameter   :取值范围

示例:

SELECT REGEXP_SUBSTR('11,22,33','[^,]+',1,LEVEL) AS STR FROM DUAL 
CONNECT BY LEVEL <= LENGTH('11,22,33')-LENGTH(REGEXP_REPLACE('11,22,33',',','')) + 1

这样就能将IN的集合处理成SQL的查询结果集了,直接通过JOIN语句连接就可以了,现在将上面的SQL处理成这种写法。

SELECT u.* FROM T_USER u 
INNER JOIN (
    SELECT REGEXP_SUBSTR('114664882678267904,114457962503733248,114658384933814272','[^,]+',1,LEVEL) USER_ID FROM DUAL  
    CONNECT BY  LEVEL <= LENGTH('114664882678267904,114457962503733248,114658384933814272')-LENGTH(REGEXP_REPLACE('114664882678267904,114457962503733248,114658384933814272',',','')) + 1 
) t ON u.USER_ID = t.USER_ID;

现在,是不是一切都好起来了。

猜你喜欢

转载自blog.csdn.net/zhangjian8641/article/details/107691087
今日推荐