加入收藏 | 设为首页 | 会员中心 | 我要投稿 PHP编程网 - 黄冈站长网 (http://www.0713zz.com/)- 数据应用、建站、人体识别、智能机器人、语音技术!
当前位置: 首页 > 百科 > 正文

Oracle:PL / SQL中最快的方式,以查看是否存在值:List,VARRAY或

发布时间:2021-01-08 13:12:11 所属栏目:百科 来源:网络整理
导读:更新如果您想查看长原始问题,请查看编辑内容.这是问题的更简洁的短版本…… 我需要看看GroupA(不总是GroupA,这会改变每个循环迭代)是否存在于200个左右的组中的[list,varray,temp table,what].我如何存储这200个组完全由我控制.但我想将它们存储在一个有助

更新如果您想查看长原始问题,请查看编辑内容.这是问题的更简洁的短版本……

我需要看看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

解决方法

myGroup是varray吗?如果它是一个字符串尝试类似于:

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;

我不知道这是否比其他提到的解决方案更快(这是一个很好的机会),这是另一回事.

(编辑:PHP编程网 - 黄冈站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读