存在vs选择计数

时间:2013-02-21 15:11:40

标签: sql-server oracle plsql

在SQL Server中,性能方面,最好使用IF EXISTS (select * ...)而不是IF (select count(1)...) > 0 ...

但是,看起来Oracle在EXISTS语句中不允许IF,这样做会有什么替代方法,因为使用IF select count(1) into...的性能非常低效?

代码示例:

IF (select count(1) from _TABLE where FIELD IS NULL) > 0 THEN
UPDATE TABLE _TABLE
SET FIELD = VAR    
WHERE FIELD IS NULL;
END IF;

2 个答案:

答案 0 :(得分:6)

编写代码段的最佳方法是

UPDATE TABLE _TABLE
SET FIELD = VAR    
WHERE FIELD IS NULL;

即。只是做更新。它会处理行还是不处理。如果你需要检查它是否确实处理了行,那么之后再添加

if (sql%rowcount > 0)
then
...

通常在你有

之类的逻辑的情况下
declare
  v_cnt number;
begin
select count(*) 
  into v_cnt 
  from TABLE 
 where ...;

if (v_cnt > 0) then..

最好使用ROWNUM = 1,因为如果有4000万行你就不关心了......只有在找到1行后Oracle才会停止。

declare
  v_cnt number;
begin
select count(*) 
  into v_cnt 
  from TABLE 
 where rownum = 1
   and ...;

if (v_cnt > 0) then..

select count(*) 
  into v_cnt 
  from dual
 where exists (select null 
                 from TABLE
                where ...);

您喜欢哪种语法。

答案 1 :(得分:2)

按照: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:3069487275935

你可以尝试:

  for x in ( select count(*) cnt
               from dual 
              where exists ( select NULL from foo where bar ) )
  loop
        if ( x.cnt = 1 ) 
        then
          found do something
        else 
          not found
        end if;
  end loop;

是一种方式(非常快,只有在“需要”时才运行子查询,存在 在点击第一行后停止子查询)

该循环始终至少执行一次,并且自表上的计数(*)起最多执行一次 没有group by子句ALWAYS返回最少一行并且最多返回一行(即使是 表本身是空的!)