我需要看看GroupA(不总是GroupA,这会改变每个循环迭代)是否存在于200个左右的组中的[list,varray,temp table,what].我如何存储这200个组完全由我控制.但我想将它们存储在一个有助于最快“存在”检查的构造中,因为我必须在一个循环中针对不同的值(不总是GroupA)多次检查此列表.那么PL / sql最快,检查列表……
如果’GroupA’IN(‘GroupA’,’GroupB’)那么……
或使用会员检查VARRAY …
IF 'GroupA' MEMBER OF myGroups THEN
或以这种方式检查VARRAY ……
FOR i IN myGroups.FIRST .. myGroups.LAST LOOP IF myGroups(i) = 'GroupA' THEN v_found := TRUE; EXIT; END IF; END LOOP;
或检查关联数组……
将在明天进行测试
更新:从每个人的建议测试的最终结果
谢谢大家.
我运行了这些测试,循环了1000万次,使用LIKE的逗号分隔字符串似乎是最快的所以我想这些点必须转到@Brian McGinity(时间在下面的评论中).但由于时间都非常接近,所以我采用哪种方法可能无关紧要.我想我会使用VARRAY MEMBER OF方法,因为我可以用一行代码加载数组(批量收集),而不必循环游标来构建一个字符串(感谢@Wernfried将MEMBER OF引入我的注意力)…
逗号分隔列表,例如:,GroupA,GroupB,GroupC,…大约200个组…(通过循环游标制作的列表)
FOR i IN 1 .. 10000000 loop if myGroups like '%,NONE,%' then z:=z+1; end if; end loop; --690msec
相同的逗号分隔列表(循环游标制作的列表)…
FOR i IN 1 .. 10000000 loop if instr(myGroups,',') > 0 then z:=z+1; end if; end loop; --818msec
varray,相同的200组(散装收集的varray)……
FOR i IN 1 .. 10000000 loop IF 'NONE' MEMBER of myGroups THEN z:=z+1; end if; end loop; --780msec
@Yaroslav Shabalin建议的关联数组方法(通过循环游标制作的关联数组)…
FOR i IN 1 .. 10000000 loop if (a_values('NONE') = 1) then z:=z+1; end if; end loop; --851msec
解决方法
select 1 from dual where 'abc,def' like '%,%'
很难遵循你正在使用的约束……如果可能的话,在sql中做一切,它会更快.
更新:
所以,如果你已经在一个plsql单元中,并希望保留在一个plsql单元中,那么上面的逻辑将是这样的:
declare gp varchar2(200) := 'abc,def,higlmn,op'; begin if ','||gp||',' like '%,%' then dbms_output.put_line('y'); else dbms_output.put_line('n'); end if; end;
如果这个本身处于循环中,那么将列表设为:
declare gp varchar2(200) := 'abc,op'; gp2 varchar2(200) := ',' || gp || ','; begin if g2 like '%,%' then dbms_output.put_line('y'); else dbms_output.put_line('n'); end if; end;
也尝试instr,它可能比以下更快:
declare gp varchar2(200) := ',abc,hig,'; begin if instr(gp,') > 0 then dbms_output.put_line('y'); else dbms_output.put_line('n'); end if; end;
我不知道这是否比其他提到的解决方案更快(这是一个很好的机会),这是另一回事.