HASH,百度百科上做如下定义:

Hash,一般翻译做“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射, pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。

如此生硬的定义很难理解,我们来点看的见的,CHECKSUM就是一种典型的HASH操作

--==========================================================
SELECT CHECKSUM('SLDKSLKFJDSLKJFDSLAKJF;DSAKLFJDSJASLKF S')
--值为244224724 SELECT CHECKSUM('中啥打算换阿盛大连水库将盛大阿克苏打算快乐撒旦')
--值为1349490807 --==============================================================
SELECT CHECKSUM(REPLICATE(CAST('中啥打算换阿盛大连水库将盛大阿克苏打算快乐撒旦' AS nvarchar(MAX)),100000)) AS HashKey
,DATALENGTH(REPLICATE(CAST('中啥打算换阿盛大连水库将盛大阿克苏打算快乐撒旦' AS nvarchar(MAX)),100000)) AS DataLength
--HashKey=438180382
--DataLength=4600000

使用CHECKSUM函数,我们可以很容易根据一个任意长度的字符串得到一个整数值,而且CHECKSUM属于确定性函数,无论何时执行,相同的字符串,总是能获得同样的整数值,CHECKSUM所得值不相同的两个字符串一定不相同。由此,我们可以在比较两个长字符串是否相等时,先比较CHECKSUM的值,如果CHECKSUM值不相等则判定两个字符串不相等,如果CHECKSUM值相等则遍历每个字符是否相等。

上述操作看起来似乎比直接比较字符串更麻烦,但是不同字符串的CHECKSUM值相等的情况并不多,因此需要遍历每个字符判断相等的概率会比较低。

除了散列值存储空间更小和更容易比较外,HASH散列值还有另外一个优点:固定长度和类型,如CHECKSUM返回的就是4字节的INT类型,由于类型和存储空间相同,我们可以对散列值做进一步操作,将散列值平均分拆到不同的存储空间上,这样边有了HASH桶的概念,如我们可以将CHECKSUM返回的值做取余操作,为每个余数划分一片区域。

--====================================
--准备测试数据
SELECT name INTO HB001
FROM sys.all_objects --===================================
--查看测试数据
SELECT name AS SourceValue,
CHECKSUM(name) AS HashKey,
ABS(CHECKSUM(name)%1000) AS HashBucket
,FROM HB001
ORDER BY HashBucket

当我们有上面数据后,如果要查询表中是否有“sp_procedure_params_rowset”,我们便可以先对“sp_procedure_params_rowset”求HashKeyH和HashBucket,先根据HashBucket找到我们要去那片区域查找数据,在根据HashKey和值去匹配这片区域的数据,因此我们需要到HashBucket=2的区域下找,而HashBucket=2的区域下有3条数据,我们只需要比较这三条数据就可以了,避免了对表中数据进行遍历或排序查找。

--=================红果果的分割线=================--

对HASH有了朦胧了解后,让我们来看下HASH JOIN步骤:

1. 生成输入,在生产输入阶段,查询优化器选择一个表(或结果集,一般会选择数据量较小的对象)作为生成输入,先扫描或计算整个生成输入,然后在内存中生成哈希表。根据计算得出的哈希键的哈希值,将每行插入哈希存储桶。

2. 探测输入,当生成输入结束后,将另外一个表(结果集)作为探测输入,一次一行地对整个探测输入进行扫描或计算,并为每个探测行计算哈希键的值,扫描相应的哈希存储桶并生成匹配项。

--=================红果果的分割线=================--

除了HASH JOIN会使用到HASH外,在分组统计时,也会应用到HASH。

延用上面的数据,当我们需要依据SourceValue来分组求COUNT时,可以先将SourceValue采用HASH分拆到多个HASH桶中,由于相同的SourceValue会被分配到一个HASH桶中,因此我们在做分组统计时,只需要考虑同一个桶中是否有相同的值,而无需考虑其他HASH桶,这样就避免了我们对整个结果集排序分组的过程。

--=================红果果的分割线=================--

在做HASH相关操作时,HASH桶的数量和数据均匀分布至关重要,如果HASH桶的数量过少的话,那么每次扫描桶中数据的成本就会上升,如果HASH桶数量过多的话,过多的空桶就会造成资源浪费,数据分布不均匀的话,就会导致某些桶数据过多,某些桶数据过小,对性能也影响也很严重。请参照SQL SERVER 2014的内存表的HASH索引

学习HASH,你便不得不看下HASH WARNING

--=================红果果的分割线=================--

影响联接的一些因素

1. 联接两端的表(结果集)大小

2. 联接字段上是否排序和排序的开销

3. 联接类型是等值联接还是不等值联接

4. 服务器可用内存情况

--=================红果果的分割线=================--

换个口味,上头GP的冤家,颤栗吧,GP!

曲演杂坛--HASH的一点理解的更多相关文章

  1. 曲演杂坛--一条DELETE引发的思考

    原文:曲演杂坛--一条DELETE引发的思考 场景介绍: 我们有一张表,专门用来生成自增ID供业务使用,表结构如下: CREATE TABLE TB001 ( ID ,) PRIMARY KEY, D ...

  2. 曲演杂坛--当ROW_NUMBER遇到TOP

    值班期间研发同事打来电话,说应用有超时,上服务器上检查发现有SQL大批量地执行,该SQL消耗IO资源较多,导致服务器存在IO瓶颈,细看SQL,发现自己都被整蒙了,不知道这SQL是要干啥,处理完问题赶紧 ...

  3. 曲演杂坛--使用TRY CATCH应该注意的一个小细节

    群里一个朋友遇到一个TRY CATCH的小问题,测试后发现是自己从来没有考虑的情况,写篇blog加深下印象 --============================================ ...

  4. 曲演杂坛--重建索引后,还使用混合分区么?(Are mixed pages removed by an index rebuild?)

    原文来自:http://www.sqlskills.com/blogs/paul/mixed-pages-removed-index-rebuild/ 在SQL SERVER 中,区是管理空间的基本单 ...

  5. 曲演杂坛--蛋疼的ROW_NUMBER函数

    使用ROW_NUMBER来分页几乎是家喻户晓的东东了,而且这东西简单易用,简直就是程序员居家必备之杀器,然而ROW_NUMBER也不是一招吃遍天下鲜的无敌BUG般存在,最近就遇到几个小问题,拿出来供大 ...

  6. 曲演杂坛--特殊字符/生僻字与varchar

    对于中文版的SQL SERVER,默认安装后使用的默认排序规则为Chinese_PRC_CI_AS,在此排序规则下,使用varchar类型来可以“正常存取”存放中文字符以及一些东南亚国家的字符,同时v ...

  7. 曲演杂坛--使用CTE时踩的小坑:No Join Predicate

    在一次系统优化中,意外发现一个比较“坑”的SQL,拿出来供大家分享. 生成演示数据: --====================================== --检查测试表是否存在 IF(O ...

  8. 曲演杂坛--为什么SELECT语句会被其他SELECT阻塞?

    很多刚入门的DBA在捕获阻塞得时候,会问这么一个问题“为什么这个SELECT语句被那个SELECT语句阻塞了,难道不是共享锁么?” 让我们来做个小测试,首先准备一些测试数据: --========== ...

  9. 曲演杂坛--EXISTS语句

    通常在我写EXISTS语句时,我会写成IF EXISTS(SELECT TOP(1) 1 FROM XXX),也没细细考究过为什么要这么写,只是隐约认为这样写没有啥问题,那今天就深究下吧! 首先准备测 ...

随机推荐

  1. linux分区之gpt(大于2T的分区)

    1.文件系统限制: ext3块尺寸 最大文件尺寸 最大文件系统尺寸1KiB  16GiB  2TiB2KiB  256GiB  8TiB4KiB  2TiB  16TiB8KiB  16TiB  32 ...

  2. Island Transport

    Island Transport http://acm.hdu.edu.cn/showproblem.php?pid=4280 Time Limit: 20000/10000 MS (Java/Oth ...

  3. SpringBoot中使用消息中间件Kafka实现Websocket的集群

    1.在实际项目中,由于数据量的增大及并发数的增多,我们不可能只用一台Websocket服务,这个时候就需要用到Webscoket的集群.但是Websocket集群会遇到一些问题.首先我们肯定会想到直接 ...

  4. 利用python实现二分法和斐波那契序列

    利用python实现二分法:我的实现思路如下 1.判断要查找的值是否大于最大值,如果大于则直接返回False 2.判断要查找的值是否小于最小值,如果小于则直接返回False 3.如果要查找的值在最大值 ...

  5. [leetcode]392. Is Subsequence 验证子序列

    Given a string s and a string t, check if s is subsequence of t. You may assume that there is only l ...

  6. [leetcode]112. Path Sum路径和(是否有路径)

    Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all ...

  7. Combobox实现多项选择 Silverlight下“Combobox”怎样实现多项选择?

    把 combobox里面的项换成checkedbox 示例: combobox cbb=new combobox(); ) { CheckBox cb = new CheckBox(); cb.Com ...

  8. SqlServer中批量update

    现在我有两张表分别是S_PERSON,S_USER S_PERSON S_USER 我现在想把S_USER表中的ACCOUNT批量修改成S_PERSON的ACCOUNT 我们可以发现S_USER表中有 ...

  9. phalcon框架安装

    Phalcon学习笔记 - 安装 原创 2014年10月23日 12:20:33 标签: phalcon / phalcon安装 5014 如何学习一个新的框架 1  明白工作原理 2  知道核心思想 ...

  10. div+css隐藏内容样式方法

    div css隐藏内容样式方法     div+css隐藏内容方法 一般情况下,css隐藏的用途,如下: 1.对文本的隐藏 2.隐藏超链接(另类黑链) 3.对统计代码隐藏 4.隐藏超出图片 5.css ...