曲演杂坛--HASH的一点理解
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的一点理解的更多相关文章
- 曲演杂坛--一条DELETE引发的思考
原文:曲演杂坛--一条DELETE引发的思考 场景介绍: 我们有一张表,专门用来生成自增ID供业务使用,表结构如下: CREATE TABLE TB001 ( ID ,) PRIMARY KEY, D ...
- 曲演杂坛--当ROW_NUMBER遇到TOP
值班期间研发同事打来电话,说应用有超时,上服务器上检查发现有SQL大批量地执行,该SQL消耗IO资源较多,导致服务器存在IO瓶颈,细看SQL,发现自己都被整蒙了,不知道这SQL是要干啥,处理完问题赶紧 ...
- 曲演杂坛--使用TRY CATCH应该注意的一个小细节
群里一个朋友遇到一个TRY CATCH的小问题,测试后发现是自己从来没有考虑的情况,写篇blog加深下印象 --============================================ ...
- 曲演杂坛--重建索引后,还使用混合分区么?(Are mixed pages removed by an index rebuild?)
原文来自:http://www.sqlskills.com/blogs/paul/mixed-pages-removed-index-rebuild/ 在SQL SERVER 中,区是管理空间的基本单 ...
- 曲演杂坛--蛋疼的ROW_NUMBER函数
使用ROW_NUMBER来分页几乎是家喻户晓的东东了,而且这东西简单易用,简直就是程序员居家必备之杀器,然而ROW_NUMBER也不是一招吃遍天下鲜的无敌BUG般存在,最近就遇到几个小问题,拿出来供大 ...
- 曲演杂坛--特殊字符/生僻字与varchar
对于中文版的SQL SERVER,默认安装后使用的默认排序规则为Chinese_PRC_CI_AS,在此排序规则下,使用varchar类型来可以“正常存取”存放中文字符以及一些东南亚国家的字符,同时v ...
- 曲演杂坛--使用CTE时踩的小坑:No Join Predicate
在一次系统优化中,意外发现一个比较“坑”的SQL,拿出来供大家分享. 生成演示数据: --====================================== --检查测试表是否存在 IF(O ...
- 曲演杂坛--为什么SELECT语句会被其他SELECT阻塞?
很多刚入门的DBA在捕获阻塞得时候,会问这么一个问题“为什么这个SELECT语句被那个SELECT语句阻塞了,难道不是共享锁么?” 让我们来做个小测试,首先准备一些测试数据: --========== ...
- 曲演杂坛--EXISTS语句
通常在我写EXISTS语句时,我会写成IF EXISTS(SELECT TOP(1) 1 FROM XXX),也没细细考究过为什么要这么写,只是隐约认为这样写没有啥问题,那今天就深究下吧! 首先准备测 ...
随机推荐
- bootstrap下拉框的例子,提示Error: Bootstrap's JavaScript requires jQuery
bootstrap很多js依赖jquery,所以需要引入jquery 遇到的问题: 页面访问提示:Error: Bootstrap's JavaScript requires jQuery 解 ...
- np.identity()
二.np.identity()这个函数和之前的区别在于,这个只能创建方阵,也就是N=M 函数的原型:np.identity(n,dtype=None) 参数:n,int型表示的是输出的矩阵的行数和列数 ...
- 【校招面试 之 C/C++】第25题 C++ 智能指针(一)之 auto_ptr
1.智能指针背后的设计思想 我们先来看一个简单的例子: void remodel(std::string & str) { std::string * ps = new std::string ...
- day7:vcp考试
Q121. An ESXi 6.x host in the vCenter Server inventory has disconnected due to an All Paths Down (AP ...
- 【转】Hadoop HDFS分布式环境搭建
原文地址 http://blog.sina.com.cn/s/blog_7060fb5a0101cson.html Hadoop HDFS分布式环境搭建 最近选择给大家介绍Hadoop HDFS系统 ...
- layui学习<一>
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- Santa Claus and a Place in a Class
/* Santa Claus is the first who came to the Christmas Olympiad, and he is going to be the first to t ...
- BZOJ 2726 [SDOI2012] 任务安排 - 斜率优化dp
题解 转移方程与我的上一篇题解一样 : $S\times sumC_j + F_j = sumT_i \times sumC_j + F_i - S \times sumC_N$. 分离成:$S\t ...
- lib文件反汇编
运行vc命令行,输入:dumpbin /disasm xxx.lib > test.txt lib就是obj文件打包起来的,可以用lib.exe解出来,下面是vc环境下的操作,其他环境,看命令行 ...
- tmux配置与用法整理
tmux常用命令与快捷键 http://www.111cn.net/sys/linux/59058.htm http://www.360doc.com/content/13/0709/13/13047 ...