接下来的文章是记录自己曾经的盲点,同时也透漏了自己的发展历程(可能发展也算不上,只能说是瞎混)。当然,一些盲点也在工作和探究过程中慢慢有些眉目,现在也愿意发扬博客园的奉献精神,拿出来和大家分享一下。

开门见山,直接入题

在进行Join的时候,数据库优化器是怎么进行联接呢?下面我们也详细的讲述。

在SQL Server中,有3中Join的策略——哈希匹配(Hash)、合并(Merge)、嵌套循环(Nested Loop).

在理解者三种联接策略之前,我们先来简单了解下哈希匹配联接、合并联接、嵌套循环联接,

哈希匹配联接:这种联接有两种输入,即建立输入和探测输入。首先SQL Server会根据统计信息从两张表中筛选出较小的表作为建立输入,并且读入所有行,然后在内存中根据关联条件建立一个哈希表。在整个建立阶段完成之后就进入探测阶段。以后一行一行的对探测输入进行扫描和计算,并为每个探测行计算哈希值,然后进行匹配(当然这里也分多种情况,建立输入大于可用内存时等其他情况)。

合并联接:合并连接要求两个输入都要在合并列上排序。由于每个输入都已排序,因此Merge Join运算符将从每个输入中获取一行进行比较,如果行相等则进行返回,不等则舍弃。当数据量不大的时候,这种联接方式比哈希匹配更加有效。

嵌套循环联接:嵌套循环也称“嵌套迭代”,他将一个联接输入用作外部输入表,将另一个联接输入用作内部输入表。外部循环逐行处理外部输入表。内部循环逐行处理外部输入表,内部循环会针对每个外部行执行,在内部输入表中搜索匹配的行。

通过上面的介绍,我们也能分析出来(可以根据时间复杂度,和空间复杂度),以上三种联接并没有绝对的优劣。

大致可以分一下几种情况:

(1)当数据量容量很大,且未排序的情况下,哈希匹配要优于其他两种。

(2)当属数据已经排序,且数据量不大的之后,合并连接更加有效。

(3)当结果集比较小,且数据容量不大的时候嵌套循环比较合适。

下面我们可以通过测试来查看SQL Server优化器的选择。

我们先创建两张表(Headers和Details):

1.执行下面查询,查看执行计划:

select *

from Headers

inner join Details on Headers.ID=Details.HeaderID

go

2.查看执行计划,可以看出查询优化器使用了哈希匹配:

3.在两表中创建聚集索引

create nonclustered index index_details_headerID on details(headerID)

create unique clustered index index_details_ID_headerID on details(headerID,ID)

4、执行上面查询,开启执行计划,可以看出此时优化器使用了合并联接

5.现在执行下面查询语句(带where 过滤):

select *from Headers inner join Details on Headers.ID=Details.HeaderID where Details.ID=500

6.通过查看执行计划得出,当结果集比较小的时候优化器选择了嵌套循环:

总结

通过上面的我们可以得出,三种联接各有优略,视乎情况而定。但是如果可以的话,应该在关联列上建立索引。

SQL Server执行计划那些事儿(1)——哈希、合并、嵌套联接的选择的更多相关文章

  1. SQL Server执行计划那些事儿(3)——书签查找

    接下来的文章是记录自己曾经的盲点,同时也透漏了自己的发展历程(可能发展也算不上,只能说是瞎混).当然,一些盲点也在工作和探究过程中慢慢有些眉目,现在也愿意发扬博客园的奉献精神,拿出来和大家分享一下. ...

  2. SQL Server执行计划那些事儿(2)——查找和扫描

    接下来的文章是记录自己曾经的盲点,同时也透漏了自己的发展历程(可能发展也算不上,只能说是瞎混).当然,一些盲点也在工作和探究过程中慢慢有些眉目,现在也愿意发扬博客园的奉献精神,拿出来和大家分享一下. ...

  3. SQL Server 执行计划缓存

    标签:SQL SERVER/MSSQL SERVER/数据库/DBA/内存池/缓冲区 概述 了解执行计划对数据库性能分析很重要,其中涉及到了语句性能分析与存储,这也是写这篇文章的目的,在了解执行计划之 ...

  4. sql server 执行计划(execution plan)介绍

    大纲:目的介绍sql server 中执行计划的大致使用,当遇到查询性能瓶颈时,可以发挥用处,而且带有比较详细的学习文档和计划,阅读者可以按照我计划进行,从而达到对执行计划一个比较系统的学习. 什么是 ...

  5. SQL Server 执行计划中的扫描方式举例说明

    SQL Server 执行计划中的扫描方式举例说明 原文地址:http://www.cnblogs.com/zihunqingxin/p/3201155.html 1.执行计划使用方式 选中需要执行的 ...

  6. 引用:初探Sql Server 执行计划及Sql查询优化

    原文:引用:初探Sql Server 执行计划及Sql查询优化 初探Sql Server 执行计划及Sql查询优化 收藏 MSSQL优化之————探索MSSQL执行计划 作者:no_mIss 最近总想 ...

  7. SQL Server 执行计划操作符详解(3)——计算标量(Compute Scalar)

    接上文:SQL Server 执行计划操作符详解(2)--串联(Concatenation ) 前言: 前面两篇文章介绍了关于串联(Concatenation)和断言(Assert)操作符,本文介绍第 ...

  8. SQL Server 执行计划操作符详解(2)——串联(Concatenation )

    本文接上文:SQL Server 执行计划操作符详解(1)--断言(Assert) 前言: 根据计划,本文开始讲述另外一个操作符串联(Concatenation),读者可以根据这个词(中英文均可)先幻 ...

  9. 浅析SQL SERVER执行计划中的各类怪相

    在查看执行计划或调优过程中,执行计划里面有些现象总会让人有些疑惑不解: 1:为什么同一条SQL语句有时候会走索引查找,有时候SQL脚本又不走索引查找,反而走全表扫描? 2:同一条SQL语句,查询条件的 ...

随机推荐

  1. LDA 资料整理

    LDA 中文名叫 隐含狄利克雷分布 有一个讲的数学八卦的pdf,如下: http://pan.baidu.com/s/1bnX6Pgb Latent Dirichlet Allocation(LDA) ...

  2. Caused by: java.lang.ClassNotFoundException: com.mchange.v2.c3p0.ComboPooledDataSource

    1.错误描写叙述 usage: java org.apache.catalina.startup.Catalina [ -config {pathname} ] [ -nonaming ] { -he ...

  3. java中substring的使用方法

    java中substring的使用方法 str=str.substring(int beginIndex);截取掉str从首字母起长度为beginIndex的字符串,将剩余字符串赋值给str: str ...

  4. 安装Discuz!论坛时提示“mysqli_connect() 不支持 advice_mysqli_connect”

    安装Discuz!论坛时提示“不支持Mysql数据库,无法安装论坛”的解决方法1,在系统的 system32(C:\windows\system32)目录下缺少libmysql.dll文件,解决方法是 ...

  5. 张冬:OpenPOWER CAPI为什么这么快?(二)

     张冬:OpenPOWER CAPI为什么这么快?(二) PMC公司数据中心存储架构师张冬 有了CAPI的FPGA是怎么做的? 首先认识一下这个体系里的三个角色: AFU(Acceleration ...

  6. Linux学习4——Vim和Bash

    一.写在前面  本将将介绍Linux自带的强大的文本编辑器Vim和Bash的相关知识. 二.完成目标 1.了解Vim和Bash的基本概念 2.定制自己的vim 3.Bash中的一些命令 4.管道命令 ...

  7. 02Android用户界面优化之(一)Android Fragment

    一.使用Fragment 1.AndroidManifest.xml文件 <?xml version="1.0" encoding="utf-8"?> ...

  8. 使用ADO.net中的链接字符串

    需要引用:System.Configuration命名空间 ConfigurationManager.ConnectionStrings["sqlConnStr"].Connect ...

  9. Visual C++ 64bit应用程序项目设置

    Visual Studio 2005 This topic describes how to set up C++ applications to target 64-bit platforms us ...

  10. Git教程--Git安装和版本库的创建

    Git的诞生 很多人都知道,Linus在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了. Linus虽然创建了Linux,但Linux的壮大是靠全世界热 ...