zoukankan      html  css  js  c++  java
  • IN與EXISTS的性能比較示例

     

    很多朋友對INEXISTS的使用存在疑問﹐為什么IN就比EXISTS的性能差呢﹖首先大家得了解如何使用查询分析器查看T-SQL/SQL的执行计划,以及如何在SQLSERVER数据库的帮助中查看相关信息。

    图一

    图二

           在执行图一中后两个SQL语句前,必须打开“显示执行计划”开关,按CTRL+K组合键,按F5执行后,返回同样的记录,查询成本却相去甚远,为什么呢?使用EXISTS的查询在执行计划中使用了NESTED LOOPSLEFT SEMI JOIN等运算符;而使用IN的查询在执行中使用了HASH MATCHRIGHT SEMI JOIN运算符。      SQLSERVER的联机帮助中,输入NESTED LOOP等可以看到它们的说明。

     

    关于嵌套循环联接

    嵌套循环联接也称为嵌套迭代,它将一个联接输入用作外部输入表(显示为图形执行计划中的顶端输入),将另一个联接输入用作内部(底端)输入表。外部循环逐行消耗外部输入表。内部循环为每个外部行执行,在内部输入表中搜索匹配行。最简单的情况是,搜索时扫描整个表或索引;这称为单纯嵌套循环联接。如果搜索时使用索引,则称为索引嵌套循环联接。如果将索引生成为查询计划的一部分(并在查询完成后立即将索引破坏),则称为临时索引嵌套循环联接。查询优化器考虑所有这些不同形式。如果外部输入很小而内部输入很大且预先创建了索引,则嵌套循环联接尤其有效。在许多小事务中(如那些只影响较小的一组行的事务),索引嵌套循环联接远比合并联接和哈希联接优越。但在大查询中,嵌套循环联接通常不是最佳选择。

    了解哈希联接

    哈希联接有两种输入:生成输入和探测输入。查询优化器指派这些角色,使两个输入中较小的那个作为生成输入。

    哈希联接可用于许多类型的集合匹配操作:内联接,左向外联接、右向外联接和完整外联接,左向半联接和右向半联接、交集、联合和差分。而且,哈希联接的变化形式能够进行重复项删除和分组操作(如 SUM(salary) GROUP BY department)。这些修改对生成和探测角色只使用一个输入。

    与合并联接相似,只有当联接谓词中至少有一个等效 (WHERE) 子句时才能使用哈希联接。然而,联接一般用于重组合由主键和外键之间的等效谓词表达的关系,因此大多数联接至少有一个等效子句。用等效谓词表达的列集合称为哈希键,因为这些列有助于哈希函数。还可以有附加的谓词,并且可以将这些谓词取值为驻留谓词以与哈希值比较分开。哈希键可以是表达式,只要能从单个行中的列对其进行排它计算。在分组操作中,按列表分组的列是哈希键。在交集等集合操作中以及删除复制项时,哈希键由所有列组成。

    内存中的哈希联接

    哈希联接先扫描或计算整个生成输入,然后在内存中生成哈希表。根据为哈希键计算出的哈希值,将每行插入哈希存储桶。如果整个生成输入比可用内存少,则可以将所有行都插入哈希表中。生成阶段后接着是探测阶段。一次一行地对整个探测输入进行扫描或计算,并为每个探测行计算哈希键的值,扫描相应的哈希存储桶并生成匹配项。

    Grace 哈希联接

    如果生成输入不适合内存,哈希联接将分步进行。每一步都包括生成阶段和探测阶段。首先,消耗整个生成和探测输入并(使用哈希键上的哈希函数)将其分区为多个文件。这类文件的数目称为分区输出端。通过使用哈希键上的哈希函数,可以保证任意两个联接记录必在相同的文件对中。因此,联接两个大输入的任务简化为相同任务的多个较小的实例。然后将哈希联接应用于每对分区文件。

    递归哈希联接

    如果生成输入非常大,以至于标准外部合并排序的输入需要多个合并级别,则需要多个分区步骤和多个分区级别。如果只有某些分区较大,则只需对这些分区使用附加的分区步骤。为使所有的分区步骤尽可能快,将使用大的异步 I/O 操作以便单个线程就能使多个磁盘驱动器繁忙工作。

    说明  如果生成输入较大但并不比可用内存大很多,则内存中的哈希联接和 Grace 哈希联接的元素将合并成一个步骤,产生混合哈希联接。

    在优化过程中并不总能确定使用什么样的哈希联接。因此,Microsoft® SQL Server™ 2000 开始时使用内存中的哈希联接,然后根据生成输入的大小逐渐转换到 Grace 哈希联接和递归哈希联接。

    如果优化器错误地预计两个输入中哪个较小并由此确定哪个作为生成输入,生成角色和探测角色将动态逆转。哈希联接确保使用较小的溢出文件作为生成输入。这一技术称为角色逆转。

  • 相关阅读:
    Unity3d资源管理分析
    Unity3D之MonoBehaviour的可重写函数整理
    Unity3D脚本学习——运行时类
    A*寻路初探(转载)
    360sdk网游支付服务
    总结使用Unity 3D优化游戏运行性能的经验
    Unity3D之Lightmap详解
    「luogu2714」四元组统计
    「BZOJ1066」[SCOI2007]蜥蜴
    「luogu1251」餐巾计划问题
  • 原文地址:https://www.cnblogs.com/zeromyth/p/1196378.html
Copyright © 2011-2022 走看看