`
sangei
  • 浏览: 336527 次
  • 性别: Icon_minigender_1
  • 来自: 西安
社区版块
存档分类
最新评论

(转)in 和 exist

阅读更多

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'的结果是相同的。

 

EXISTS、IN与JOIN,都可以用来实现形如“查询A表中在(或不在)B表中的记录”的查询逻辑。

在查询的两个表大小相当的情况下,3种查询方式的执行时间通常是:
EXISTS <= IN <= JOIN
NOT EXISTS <= NOT IN <= LEFT JOIN
只有当表中字段允许NULL时,NOT IN的方式最慢:
NOT EXISTS <= LEFT JOIN <= NOT IN

但是如果两个表中一个较小,一个较大,则子查询表大的用exists,子查询表小的用in,因为in 是把外表和内表作hash 连接,而exists是对外表作loop循环,每次loop循环再对内表进行查询。而无论那个表大,用not exists都比not in要快。这是因为如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引;而not extsts 的子查询依然能用到表上的索引。

IN的好处是逻辑直观简单(通常是独立子查询);缺点是只能判断单字段,并且当NOT IN时效率较低,而且NULL会导致不想要的结果。
EXISTS的好处是效率高,可以判断单字段和组合字段,并不受NULL的影响;缺点是逻辑稍微复杂(通常是相关子查询)。
JOIN用在这种场合,往往是吃力不讨好。JOIN的用途是联接两个表,而不是判断一个表的记录是否在另一个表。

 

 

Hash Join概述 Hash join算法的一个基本思想就是根据小的row sources(称作build input,我们记较小的表为S,较大的表为B) 建立一个可以存在于hash area内存中的hash table,然后用大的row sources(称作probe input) 来探测前面所建的hash table。如果hash area内存不够大,hash table就无法完全存放在hash area内存中。针对这种情况,Oracle在连接键利用一个hash函数将build input和probe input分割成多个不相连的分区(分别记作Si和Bi),这个阶段叫做分区阶段;然后各自相应的分区,即Si和Bi再做Hash join,这个阶段叫做join阶段。如果在分区后,针对某个分区所建的hash table还是太大的话,oracle就采用nested-loops hash join。所谓的nested-loops hash join就是对部分Si建立hash table,然后读取所有的Bi与所建的hash table做连接,然后再对剩余的Si建立hash table,再将所有的Bi与所建的hash table做连接,直至所有的Si都连接完了。 Hash Join算法有一个限制,就是它是在假设两张表在连接键上是均匀的,也就是说每个分区拥有差不多的数据。但是实际当中数据都是不均匀的,为了很好地解决这个问题,oracle引进了几种技术,位图向量过滤、角色互换、柱状图,这些术语的具体意义会在后面详细介绍。 二. Hash Join原理我们用一个例子来解释Hash Join算法的原理,以及上述所提到的术语。考虑以下两个数据集。 S={1,1,1,3,3,4,4,4,4,5,8,8,8,8,10} B={0,0,1,1,1,1,2,2,2,2,2,2,3,8,9,9,9,10,10,11} Hash Join的第一步就是判定小表(即build input)是否能完全存放在hash area内存中。如果能完全存放在内存中,则在内存中建立hash table,这是最简单的hash join。如果不能全部存放在内存中,则build input必须分区。分区的个数叫做fan-out。Fan-out是由hash_area_size和cluster size来决定的。其中cluster size等于db_block_size * hash_multiblock_io_count,hash_multiblock_io_count在oracle9i中是隐含参数。这里需要注意的是fan-out并不是build input的大小/hash_ara_size,也就是说oracle决定的分区大小有可能还是不能完全存放在hash area内存中。大的fan-out导致许多小的分区,影响性能,而小的fan-out导致少数的大的分区,以至于每个分区不能全部存放在内存中,这也影响hash join的性能。 Oracle采用内部一个hash函数作用于连接键上,将S和B分割成多个分区,在这里我们假设这个hash函数为求余函数,即Mod(join_column_value,10)。这样产生十个分区,如下表. 经过这样的分区之后,只需要相应的分区之间做join即可(也就是所谓的partition pairs),如果有一个分区为NULL的话,则相应的分区join即可忽略。 在将S表读入内存分区时,oracle即记录连接键的唯一值,构建成所谓的位图向量,它需要占hash area内存的5%左右。在这里即为{1,3,4,5,8,10}。 当对B表进行分区时,将每一个连接键上的值与位图向量相比较,如果不在其中,则将其记录丢弃。在我们这个例子中,B表中以下数据将被丢弃 {0,0,2,2,2,2,2,2,9,9,9,9,9}。这个过程就是位图向量过滤。 当S1,B1做完连接后,接着对Si,Bi进行连接,这里oracle将比较两个分区,选取小的那个做build input,就是动态角色互换,这个动态角色互换发生在除第一对分区以外的分区上面。
分享到:
评论

相关推荐

    IN 和 EXIST的区别

    标题和描述均聚焦于SQL语言中“IN”和“EXISTS”的区别,这是数据库查询语言中两种常用的子查询处理方式,它们在功能上虽然相似,但在执行效率、索引使用以及适用场景上存在显著差异。 ### IN关键字 “IN”主要...

    in exist not_in

    IN、EXISTS、NOT EXISTS、NOT IN 在 SQL 语句中的应用和区别 IN 语句和 EXISTS 语句都是 SQL 语句中用来判断是否存在某个值的语句,但是它们的实现机制和应用场景是不同的。 IN 语句是通过 hash 连接来实现的,它...

    SQL中对not in和not exist查询的替代算法.pdf

    "SQL中对not in和not exist查询的替代算法.pdf" 本文主要讨论了SQL中对not in和not exist查询的替代算法。首先,作者简要介绍了SQL语言的基本概念和特点,然后讨论了not in和not exist查询的低效性及其原因。接着,...

    Some projects cannot be imported because they already exist in the workspace

    在使用Eclipse或MyEclipse等集成开发环境(IDE)时,可能会遇到“Some projects cannot be imported because they already exist in the workspace”的问题。这个错误提示表明,你试图导入的项目与当前工作空间...

    FILE_DOES_NOT_EXIST

    在 Windows 操作系统中,`FILE_DOES_NOT_EXIST` 是一个错误代码,通常表示尝试访问的文件不存在于指定的位置。该错误代码在内核模式下通过 `NTSTATUS` 类型来表示,具体的值定义为 `0x00000005`。当应用程序或驱动...

    经典SQL查询总结关于Exists,not Exists.in ,not in效率的说明。

    **IN** 和 **NOT IN** 子句通常用于检查主查询中的某字段的值是否存在于(或不存在于)子查询返回的集合中。 1. **IN** - **语法结构**: ```sql SELECT * FROM t1 WHERE t1.c1 IN (SELECT c2 FROM t2); ``` ...

    Oracle In和exists not in和not exists的比较分析

    in和exist的区别 从sql编程角度来说,in直观,exists不直观多一个select, in可以用于各种子查询,而exists好像只用于关联子查询 从性能上来看 exists是用loop的方式,循环的次数影响大,外表要记录数少,内表就...

    简述Oracle中in和exists的不同

    且看接下来的具体分析:in其实是将外表和内表进行hash join,exists是先对外表进行loop操作,然后每次loop后再对内表进行查询。 如果两张表大小差不多,那么exists和in的效率差不多。 例如: 一张大表为A,一张小表B...

    “exists”和“in”的效率问题

    ### "Exists"与"In"的效率问题详解 #### 引言 在数据库查询语言SQL中,“Exists”与“In”是两种常用的子查询方法,它们在实际应用中各有优势与局限。本文将深入探讨这两种方法的工作原理、应用场景以及性能差异,...

    Serv_U 安全设置以后出现530 Not logged in, home directory does not exist的解决方法

    一般情况都是因为文件的上级目录不存在浏览权限。...详细说明:Serv_U安装设置以及530 Not logged in, home directory does not exist解决方法安装程序尽量采用最新版本,避免采用默认安装目录,设置好serv-u

    Not-exist-in-douban:豆瓣不存在的书影音

    1. **获取项目**:首先,你需要下载或克隆`Not-exist-in-douban-master`压缩包,这通常通过Git工具完成。如果你不熟悉Git,也可以直接下载ZIP文件。 2. **理解项目结构**:解压后,你会看到一个包含`index.md`文件...

    iptables删除命令中的相关问题.doc

    最近在做一个V*P*N中间件的配置工作,在配置...iptables: Bad rule (does a matching rule exist in that chain?)。我就纳闷了,怎么会出现这个问题,按照官方的文档也有错?以下是我针对iptables删除命令的解决办法。

    SQL优化之针对count、表的连接顺序、条件顺序、in及exist的优化

    本文将深入探讨四个关键的SQL优化策略:count、表的连接顺序、条件顺序以及in和exist的使用。 首先,让我们关注`count()`函数的优化。通常认为`count(*)`统计所有行,而`count(列名)`只计算指定列的非空值。许多人...

    Getting the number of columns in report view获得列表视图的列

    "Getting the number of columns in report view"这个主题是关于如何获取列表视图中的列数,这对于界面设计、数据分析以及用户交互优化具有重要意义。下面我们将深入探讨这一话题。 首先,我们需要理解列表视图...

    MySQL数据库优化SQL篇PPT课件.pptx

    从执行计划、SELECT语句、IN和EXIST语句、LIMIT语句、RAND函数、Order by、Group by、Distinct和Count等方面对MySQL数据库优化进行了详细的讲解。 一、执行计划 执行计划是MySQL数据库优化的重要步骤。执行计划...

    MySQL exists 和in 详解及区别

    MySQL中的`EXISTS`和`IN`都是在SQL查询中用来检查某条记录是否符合特定条件的子查询操作符,但它们的工作原理和使用场景有所不同。 `EXISTS`子查询主要检查子查询是否能返回至少一行数据。在这个过程中,子查询的...

    sql语句优化之用EXISTS替代IN、用NOT EXISTS替代NOT IN的语句

    在查询中,我们可以使用EXISTS和NOT EXISTS来代替IN和NOT IN。例如,我们要查询Sendorder表中的冗余数据(没有和reg_person或worksite相连的数据): ```sql select Sendorder.id, Sendorder.reads, Sendorder....

    MYSQL IN 与 EXISTS 的优化示例介绍

    在SQL查询优化中,`IN` 和 `EXISTS` 子句经常被用来过滤结果集,但它们在执行效率上存在显著差异。了解这些差异并根据数据集的大小选择合适的子句是数据库性能调优的关键。 ### `IN` 与 `EXISTS` 原理 `IN` 子句...

Global site tag (gtag.js) - Google Analytics