oracleexist的简单介绍
本篇文章给大家谈谈oracleexist,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、oracle中in和exist的区别
- 2、oracle in和exists的区别
- 3、oracle数据库中可以用 if exists 吗,我用为什么报错
- 4、ORACLE中怎么使用exists来判断是否存在记录
- 5、oracle中exists用法?
oracle中in和exist的区别
in和exist的主要区别裤樱体现在缓空对sql执行计划的影响上。
传统上认为,如果子查询的条件更具选择性(selective),就用in;而如果父查询(外层查询)的条件更具选择扰纯瞎性(selective),就用exist。
具体的内容可以参考以下oracle原厂的手册,oracle的原厂手册都是英文版的。
另外需要特别注意的是,in和exist的区别只在10.2.0.3及以前的版本中存在;而10.2.0.4及以后的版本中,in和exist的效果是完全一样的,手册中也删除了有关二者区别的说明。
以下是对手册的引用:
In certain circumstances, it is better to use IN rather than EXISTS. In general, if the selective predicate is in the subquery, then use IN. If the selective predicate is in the parent query, then use EXISTS.
Sometimes, Oracle can rewrite a subquery when used with an IN clause to take advantage of selectivity specified in the subquery. This is most beneficial when the most selective filter appears in the subquery and there are indexes on the join columns. Conversely, using EXISTS is beneficial when the most selective filter is in the parent query. This allows the selective predicates in the parent query to be applied before filtering the rows against the EXISTS criteria.
oracle in和exists的区别
in 和 exists区别
in 是把外表和内表作瞎瞎hash join,而exists是对外表作loop,每次loop再对内表进行查询。握配
一直以来认为exists比in效率高的说法是不准确的。
如果查询的两个表大小相当,那么用in和exists差别不大。
如果两个表中一个较小,一个是大表,则子查询表大的用exists,子查询表小的用in:
例如:表A(小表),表B(大表)
1:
select * from A where cc in (select cc from B)
效率低,用到了A表上cc列的索引;
select * from A where exists(select cc from B where cc=A.cc)
效率高,用到了B表上cc列的索引。
相反的
2:
select * from B where cc in (select cc from A)
效率高,用到了B表上cc列的索引;
select * from B where exists(select cc from A where cc=B.cc)
效率低,用到了A表上cc列的索磨皮空引。
带in的关联子查询是多余的,因为in子句和子查询中相关的操作的功能是一样的。如:
select staff_name from staff_member where staff_id in
(select staff_id from staff_func where staff_member.staff_id=staff_func.staff_id);
为非关联子查询指定exists子句是不适当的,因为这样会产生笛卡乘积。如:
select staff_name from staff_member where staff_id
exists (select staff_id from staff_func);
not in 和not exists
如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;
而not extsts 的子查询依然能用到表上的索引。
所以无论哪个表大,用not exists都比not in要快。
尽量不要使用not in子句。使用minus 子句都比not in 子句快,虽然使用minus子句要进行两次查询:
select staff_name from staff_member where staff_id in (select staff_id from staff_member minus select staff_id from staff_func where func_id like '81%');
in 与 "=" 的区别
select name from student where name in ('zhang','wang','li','zhao');
与
select name from student where name='zhang' or name='li' or name='wang' or name='zhao'
的结果是相同的。
[img]oracle数据库中可以用 if exists 吗,我用为什么报错
对于Oracle中没有 if exists(...) 的语法,目前有许多种解决方法,这里先分析常用的三种,推荐使用最后一种
第一种是最常用的,判断count(*)的值是否为零,如下
declare
v_cnt number;
begin
select count(*) into v_cnt from T_VIP where col=1;
if v_cnt = 0 then
dbms_output.put_line('无记录');
end if;
end;
首先这种写法让人感觉很奇怪,明明只需要知道表里有没有记录,却去统计了全表的记录数。
这种方式对于小表而言可以接受,一旦表记录很多的时候,性能问题就非常严重
因此有人就作了些修嫌郑物改,改成 select count(*) into v_cnt from T_VIP where col=1 and rownum=1
看起来似乎解决了性能问题,但是分析执行计划可以知道,实际上是一样的,不推荐使用。
第二种是所谓进攻式编程,不作预先判断,而是直接默认通过判断,然后使用 exception 来捕获异常
比如我这里不判断表中是否有满足条件的记录,默认它有,如果没有就在异常中进行处理
declare
v_1 number;
begin
select vip_level into v_1 from T_VIP where 1=0;
exception
when no_data_found then
dbms_output.put_line('无记录');
end;
这种方式从性能上讲比第一种要好得多
不过首先它没办法适应所有的情况,如第一段代码它就没办法改造
其次这种代码看起来让人觉得好像是发生了异常,而不是正常运行,从而造成混乱,不推荐使用。
第三种是利用 Oracle 原有的 Exists 语法,如下
declare
v_cnt number;
begin
select count(*)
into v_cnt
from dual
where exists (select * from t_vip where col=1);
if v_cnt = 0 then
dbms_output.put_line('无记录');
end if;
end;
通过在语句的外面套上一层dual,来使用oracle原有的exists语法
虽然和第一种看起来类似,但分析执行计划可以知道,性能比以上两种都要好得多,与MSSQL的 if exists 最接近芹液,推荐使用。
可以把判断封装成一个函数以方便使用,代码如下
CREATE OR REPLACE FUNCTION EXISTS2 (IN_SQL IN VARCHAR2)
RETURN NUMBER
IS
/**********************************************************
* 使用示例
* begin
* if EXISTS2('select * from dual where 1=1')=1 then
* dbms_output.put_line('有记录');
* else
* dbms_output.put_line('无记录');
* end if;
* end;
*****************************************************************/
V_SQL VARCHAR2(4000);
V_CNT NUMBER(1);
BEGIN
V_SQL := 'SELECT COUNT(*) FROM DUAL WHERE EXISTS (' || IN_SQL || ')';
EXECUTE IMMEDIATE V_SQL INTO V_CNT;
RETURN(V_CNT);
END;
-
对于常用的insert判丛搜断还有更简单的写法,比如以下代码
if not exists(select * from table1 where id=1)
insert into table1 values(1,'a');
可以改写成
insert
when (not exists(select * from table1 where id=1)) then
into table1
select 1 as id, 'a' as data from dual;
-
再比如以下的代码
if not exists(select * from table1 where id=2)
insert into table1 values(2,'b')
else
update table1 set data='b' where id=2;
可以改写成
merge into table1 his
using
(
select 2 as id, 'b' as data from dual
) src
on (his.id=src.id)
when matched then
update set his.data=src.data where id=src.id
when not matched then
insert values(src.id,src.data);
-
这里附带说下,有人喜欢把count(*)写成count(列名),不推荐后一种,因为列名是需要额外的操作,去查询系统表来定位列信息
另外count(1)和count(*)没有差别,推荐使用count(*)直观明了
ORACLE中怎么使用exists来判断是否存在记录
如下:如果t表中的usercode在a表的customerno中存在相等的记竖悉录,则t表中的记录被查询出来。余蔽乎
select t.*
from llclaimuser t
where 1 = 1
and exists (select a.customerno from ldperson a where a.customerno = t.usercode);
exists的写法相对比较复杂,而且exists只能判断是否存在,不能返回具体的条数,不能进行相应的循环处理,也不见的比count(1)效率好多少,所以用你这种写法基本就可以了,简单明了,好维护,如果需要还可以根并悄据查询出的记录数进行循环。
oracle中exists用法?
exists可以说是oracle数据库开发中比较常见的用法,用exists可以提高sql的效率,可以取代in。
比如 a,b 关联列为 a.id = b.id,现在要取 a 中的数据,其中id在游中b中也存在:
select * from a where exists(select 1 from b where a.id = b.id)
现在要取 a 中的数据,其中id在b中 不存在:
select * from a where not exists(select 1 from b where a.id = b.id)
用法详解
exists是判断exits后面的sql语句是否为真,若为真则整个sql句子成立,否则没有任何记录。例子:
select 1 from dual where exists (select 1 from dual where 2=1);
上面的情况肯定是没有记录。
select 1 from dual where exists (select 1 from dual where 1=1);
上面的情况是有记录返回的。
判断另外的表中是否包含某个表的外键记录。例神唯山子:
select * from table_test a
where exists (select 1 from scott.carol_tmp where pps_master=a.pps_master);
这个sql是要检查table_test中的pps_master是否在carol_tmp中。其实用in也可以实现同样的效果,但是in的话效率要低些,特别是碰上一些大表。用exists和in的性能就山慧体现出来了。
关于oracleexist和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。