第5周 堆表

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
简介: 原文:第5周 堆表欢迎来到SQL Server性能调优培训的第2个月。这个月将会是最有趣和最有挑战性的一个月,这个月我们专一只谈SQL Server中的索引,索引,还是索引。相信我,值得一个月去学习索引。
原文: 第5周 堆表

欢迎来到SQL Server性能调优培训的第2个月。这个月将会是最有趣和最有挑战性的一个月,这个月我们专一只谈SQL Server中的索引,索引,还是索引。相信我,值得一个月去学习索引。

今天我会谈下堆表(Heap Tables),在接下来的3周,我们会探讨下聚集索引,非聚集索引,还有SQL Server的索引战略。先来看下堆表。堆表就是没有聚集索引的表。如果SQL Server中的表能有一个聚集索引,那这个表被称为聚集表(Clustered Table),没有聚集索引(/非聚集索引)的表,我们称它为堆表。

在堆表里,数据没有任何方式的排序,它就是一个无序堆,无结构关联的记录。当你使用SELECT语句访问堆表时,SQL Server在执行计划里会使用表扫描(Table Scan)运算符,因为你没有定义合适的聚集索引。(堆表)没有表查找(Table Seek)这个运算符。这点非常重要。

下周你会学到,当我们提到聚集索引时,你是通过聚集索引扫描(Clustered Index Scan)、聚集索引查找(Clustered Index Seek)运算符来访问聚集索引的。在堆表你只有一个表扫描(Table Scan)运算符。表扫描意味着你必须扫描整张表,不以你表拥有的数据量来衡量。你的数据量越多,操作花费(时间)越长。

表扫描始终是个线性O(n)操作(更多关于大O介绍),它不以你越来越大的表来衡量。现在让我们一起详细看下在SQL Server中堆表的优点和缺点。

优点

堆表插入数据非常,非常,非常快。如我们刚才说的堆表就是一个数据堆。当你从传统电话本(拆开装订)把每页扯出来并把各页放在你面前的桌上时,你就拥有了一个堆表。在堆表的电话本里插入一个新的电话记录非常快:你分配一个8kb 的新页,在那页写上新的纪录,最后把那页与面前的其他页放一起,搞定。不需要保证任何的排序。

在SQL Server里是一样的:分配一个新页,在新页存新的纪录,把这页分配给堆表,搞定。这是一个非常快的方法,因为SQL Server不需要保证任何的排序。把新纪录存放在哪里完全由SQL Server自己决定。

因此在数据库架构里,这样的表设计有些时候是非常好的主意:这些表只有海量(huge)并行(parallel)的INSERT活动。考虑下你的登陆/审计表。当我绝不推荐在任何地方使用堆表。这里只是一些特定有意义的使用案例。但不是任何地方。

缺点

堆表除了插入数据非常快的优点外,也有很多缺点,当你决定创建堆表时若不考虑这些就不合适了。

第一个缺点,堆表在你访问表数据时会在存储子系统引发随机存取(random I/O) 。想象下对你的堆表执行简单的SELECT语句。如果数据没有缓冲在缓冲池,SQL Server会发起从你的存储系统进行物理读操作。这些读操作会是随机存取(random I/O),因为堆表的页是存在数据文件里某些地方的,它们并不相邻。

如果你使用传统的旋转存储(现在大多数情况还是这样的机械硬盘),在你的存储级别就有性能上的问题,因为随机存取是非常,非常慢的。SSD硬盘在这方面是大的游戏规则改变者,因为如果你在SSD硬盘执行随机存取(random I/O) 循序存取(sqquential I/O) ,这些都不是问题。因为两种操作不管哪样速度基本都是一样(随机存取(random I/O) 循序存取(sqquential I/O) 稍微慢一点)。

另外一个是明确只有在堆表里才有的被称为转发记录(Forwarding Records) 的问题。存在堆表里的记录在某些情况下(更新变长记录会移动记录的存储)可以从一页移动到另一页。如果这个发生的话,SQL Server会在原页存放一条指向记录存放新位置的转发记录(Forwarding Record) 。

当你访问你的数据的时候,SQL Server还是访问原页,并通过转发记录拿到在额外页你需要的记录。这会让你的读性能大幅度下降。如果你想了解更多转发记录(Forwarding Record)细节,并且如何避免它们,我建议你看下我的关于那个话题的第10个SQL Server Quickie。

小结

堆表在一些情况有它们的用处。一般我都建议创建聚集表(在上面定义一个聚集索引),但想下在一些特殊案例下,堆表可能是一个服务你业务需要更好方式(利用它的性能特性)。如果你想了解更多关于什么时候使用堆表更合适的细节,我也推荐Tomas Kejser's的博客帖子 聚集索引与堆表的对抗。Tomas会给你非常有争议却仍有用的洞察,(那就是)对你来说关于什么时候使用堆表是有意义的。

下周我会探讨更多关于SQL Server中的聚集索引。你会学到如何选择你的正确聚集主键,什么时候它们是好的,还有什么时候是坏的。请继续关注,下周见。

相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
5月前
根据日期获得当天是星期几?
根据日期获得当天是星期几?
41 0
|
安全 Java Unix
第七周:函数
C语言会是你敲开编程大门的第一个语言吗?
77 0
|
机器学习/深度学习 uml
|
新零售 算法 Java
一周总结(2018-03-19)
忙着学习之前先停下来思考上周做了那些,有很多值得回忆与记录的地方,相比之前,一些变化。 上周 学习了《从0到1,设计电商平台-服务端》,《秒杀系统设计》,这两个是付费课程,不过总体来说都有收获。
977 0
|
Web App开发
一周总结(十)
又过去10天了,看上周的总结不知道自己做了什么事情,只知道每天都在赶项目进度,还记得上周有个同学聚会,其余的想不起来太多。 回顾这个10天,貌似也是每天都在赶项目进度,每天都是7点半到公司,但这几天有些放松,10点半左右就不怎么工作,打算回去了。
815 0
|
Java Spring
一周总结(八)
007的月末周时间比较长,可以经历更多的事情 上一周 每个星期的周末会和女朋友出去玩一天,上周末和女朋友在学校和女朋友会合,然后在附近玩了玩。这周末看战狼2,然后在附近椅子上休息,和同学一起喝饮料,吃牛排。
766 0
|
Spring Java
一周总结(七)
新的一周,到写东西的时候,心里有种淡淡的忧伤,没有输入,当回想自己做了什么的时候,又觉得时间浪费的很厉害。 每天8点前到公司,晚上11点回宿舍,一天工作10个小时以上。
770 0
|
前端开发 SEO
一周总结(六)
10天过去了。 10天的时间里,做了那些东西呢? 经历 前几天的时间,花一些时间和女朋友聊天,分心,去晋江找女朋友,回来开始做东西。 做东西,使用SSM,BUI前端框架,做后台系统。
721 0
|
算法 C# 索引
C# 根据年、月、周、星期获得日期等
原文:C# 根据年、月、周、星期获得日期等 [参考] http://blog.csdn.net/livening/article/details/6049341 http://zhidao.baidu.com/question/378600365.html http://www.cnblogs.com/roy117/archive/2008/03/25/1121584.html   楼上几层的代码都太多了,不用那么复杂。
1524 0
|
C++
2014秋C++ 第5周项目 初识C++
课程主页在http://blog.csdn.net/sxhelijian/article/details/39152703,课程资源在云学堂“贺老师课堂”同步展示,使用的帐号请到课程主页中查看。 【项目1-见识初学者常见错误】下面是最经典和最简单的C++程序。在ideone.com中运行程序,并在能正确运行的程序基础上,“捣乱”制造些错误,对此进行观察。经验是从错误中得来的,这个项目就是要
1171 0