Oracle:PL/SQL 中查看值是否存在的最快方法:列表、VARRAY 或临时表

2024-05-07

UPDATE如果您想查看很长的原始问题,请查看编辑。这是问题的更清晰的简短版本......

我需要看看是否GroupA(不总是GroupA,这会改变每个循环迭代)存在于大约 200 个组的 [列表、数组、临时表,等等] 中。如何存储这 200 个组完全由我控制。但我想将它们存储在一个适合最快“存在”检查的构造中,因为我必须在循环中针对不同值多次检查此列表(并不总是GroupA)。那么 PL/SQL 中最快的是什么,检查列表......

IF 'GroupA' IN ('GroupA','GroupB') THEN...

或使用 MEMBER OF 检查 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;

或检查关联数组...will test this tomorrow

更新:根据大家的建议进行测试的最终结果谢谢大家。 我运行了这些测试,循环了 1000 万次,并使用逗号分隔字符串LIKE似乎是最快的,所以我想这些点必须交给@Brian McGinity(时间在下面的评论中)。但由于时间如此接近,我采用哪种方法可能并不重要。我想我会选择VARRAY MEMBER OF方法,因为我可以用一行代码(批量收集)加载数组,而不必循环游标来构建字符串(感谢@Wernfried带来MEMBER OF引起我的注意)...

逗号分隔列表,例如:,GroupA,GroupB,GroupS,...大约 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, ',NONE,') > 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 是变量吗?如果它是一个字符串,请尝试以下操作:

select 1
  from dual
 where 'abc,NONE,def' like '%,NONE,%'

很难遵循您正在工作的约束...如果可能的话,在 sql 中完成所有操作,它会更快。

Update:

因此,如果您已经在 pl sql 单元中并且想留在 pl sql 单元中,那么上面的逻辑将如下所示:

declare
    gp varchar2(200) := 'abc,def,NONE,higlmn,op';
  begin
    if ','||gp||',' like '%,NONE,%' then
      dbms_output.put_line('y');
    else
      dbms_output.put_line('n');
    end if;
  end;

如果它本身处于循环中,则将列表制作一次:

declare
    gp varchar2(200)  := 'abc,def,NONE,higlmn,op';
    gp2 varchar2(200) := ',' || gp || ',';
  begin
    if g2 like '%,NONE,%' then
      dbms_output.put_line('y');
    else
      dbms_output.put_line('n');
    end if;
  end;

还可以尝试 instr ,它可能比类似的更快:

  declare
    gp varchar2(200) := ',abc,def,NONE,hig,';
  begin
    if instr(gp, ',NONE,') > 0 then
      dbms_output.put_line('y');
    else
      dbms_output.put_line('n');
    end if;
  end;

我不知道这是否比提到的其他解决方案更快(很有可能),这是值得尝试的其他方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Oracle:PL/SQL 中查看值是否存在的最快方法:列表、VARRAY 或临时表 的相关文章

随机推荐