设为首页 收藏本站
查看: 779|回复: 0

[经验分享] 【译】SQL Server索引进阶第六篇:书签

[复制链接]

尚未签到

发表于 2015-6-29 13:46:54 | 显示全部楼层 |阅读模式
  索引设计是数据库设计中比较重要的一个环节,对数据库的性能其中至关重要的作用,但是索引的设计却又不是那么容易的事情,性能也不是那么轻易就获取到的,很多的技术人员因为不恰当的创建索引,最后使得其效果适得其反,可以说“成也索引,败也索引”。
  本系列文章来自Stairway to SQL Server Indexes
  
  书签是什么
  我们已经在前面提到过书签,但仅仅说了书签可以帮助SQL Server快速从非聚集索引条目导向到对应的行,本篇文章开始让我们对书签的探索更进一步.书签的内容实际上是取决于非聚集索引所在表是以堆还是聚集索引存放的。
  不论表是堆结构还是段结构,可以确定的是,表中每一行都是某一页的第N行,这个某一页又是某个数据库文件的第N页,这个某个数据库文件又是构成数据库的文件组的第N个文件,因此,数据库中的每一行,在指定时间都可以由三个数字进行定位:  文件号:页号:行号。这三个数字组合起来就是所谓的RID。很多显示SQL Server内部结构的工具软件都会将这三个数字通过冒号分隔进行显示。比如,文件1的第77页的第12行的RID就是1:77:12。
  通常来说,在堆上的行不会被改变位置。一旦它们被插入某个页中,它们就会一直呆在那。如果要用更严谨的技术术语来说的话:在堆上的行很少移动。如果行被移动的话,它们会在原来的位置留下指向其移动到的位置的指针。而由聚集索引组织的行,是可以被移动的,行在改动数据或是整理索引的时候要被移动位置。更多的细节会在本系列文章后续篇幅进行介绍。
  因为在堆上的行几乎很少移动,所以RID就可以唯一标识某一行。RID的值不仅仅不变,RID所表示行的物理位置也不会变。这使得RID的值更适宜作为书签。这也是为什么SQL Server在堆上建立的非聚集索引的书签都使用RID。
  
  堆上的非聚集索引:基于RID的书签
  假如SalesOrderDetail是一个基于堆的表;表中的每行都不是有序的。下面让我们建立以ProductID/ModifiedDate为非聚集索引键并包含OrderQty, UnitPrice, LineTotal三个列的非聚集索引,如代码6.1所示。
  
CREATE NONCLUSTERED INDEX FK_ProductID_ModifiedDate
ON
Sales.SalesOrderDetail(ProductID, ModifiedDate)
INCLUDE (OrderQty,
UnitPrice, LineTotal)
  
  代码6.1 建立含有包含列的非聚集索引
  
  在上面索引中,部分数据的顺序如下所示。
DSC0000.jpg
  
  上面建立的非聚集索引因为使用了RID作为书签,直接指向对应行所在的物理地址,因此十分高效。但虽然RID值用于键查找非常高效,但书签中包含的值和具体的用户数据无关。
  另一种与这种基于RID的书签不同的书签,是当非聚集索引所在的表包含聚集索引时出现的。更准确的说,这种书签是建立聚集索引上的非聚集索引的书签。
  

在聚集索引上的非聚集索引:基于键值的书签
  如果表是基于聚集索引的,则表内数据可以在表移动。因此,对于聚集索引来说,RID并不能一直不变的定位一个相同的行。因此必须用另外的方法定位行,这个方法就是使用聚集索引的索引键。
  使用聚集索引键作为书签可以使得当数据在页中的行改变时,不需要非聚集索引的书签的值进行变动,因此非聚集索引的键就可以用于去找底层表的数据,意思是根据书签取数据不再基于物理位置,而是基于聚集索引查找。
  然而,以聚集索引键作为非聚集索引的书签最好要聚集索引键满足如下标准:
  
  索引应该具有唯一性. 每一个索引条目书签都应该使得书签可以通过聚集索引的键值唯一的确认表中的一行,如果你创建的聚集索引键值不唯一,SQL Server将会为有重复键值的每一行自动加上一个叫uniquifier的东西使得每一行唯一。这个uniquifier对客户端是透明的。对于是否可以允许聚集索引键重复,你需要考虑以下两点:


  •     生成uniquifier增加SQL Server插入操作的额外负担,在插入时SQL Server还需要判断插入的值在表中是否唯一,如果不唯一生成uniquifier值再进行插入。
  •     uniquifier本身对业务数据来说是没有意义的,但是这个uniquifier本身不仅仅需要占用聚集索引键的空间,还同时占用非聚集索引书签的空间。
  
  索引键应该短.索引键所占的字节数应该短.因为这个键还会占用非聚集索引书签的空间。比如Contact表中以Last name / first name / middle name / street组合作为索引键看上去不错,但如果表中存在多个非聚集索引的话情况就有些微妙了。n个非聚集索引使得Last name / first name / middle name / street这些字段被存储在n+1个位置。
  索引键最好不要变动.也就是索引键的值最好不要变动。对于聚集索引键的修改会使得基于这个聚集索引的所有非聚集索引同样进行修改。所以对于聚集索引的一次update会造成n个非聚集索引书签的update+1个聚集索引键值本身的update。
  
  AdventureWorks的设计团队在设计SalesOrderDetail表的聚集索引时就是完全遵循上面的建议。它们选择SalesOrderID / SalesOrderDetailID作为聚集索引键完全满足了窄,短和唯一的要求。将SalesOrderID作为索引键最左边的一列,尽管SalesOrderDetailID是唯一的,这两列组合在一起进行聚集。以SalesOrderID / SalesOrderDetailID作为主键和聚集索引键,就不再需要单独建立SalesOrderDetailID的非聚集索引了。
  现在我们创建和列表6.1所示的非聚集索引一样的索引。唯一的不同是现在这个版本是基于聚集索引而不是堆的。非聚集索引的部分数据如下:
  
DSC0001.jpg
  
  我们现在有了两个版本的非聚集索引,分别是创建在堆上的非聚集索引和创建在聚集索引上的非聚集索引,唯一的不同就是它们的书签值。
  

哪种更好
  上面两种聚集索引是不是一种要比另一种更好呢?或许吧,但是也要看具体情况。基于RID的书签允许快速的找到底层表中行所在的物理位置,而基于聚集索引的书签找到底层表的行就慢多了,但这个书签还可以作为包含列使用,书签列同时也常常会被当作外键。
  所以对于上面哪种非聚集索引更好的真正答案是”都不是”。当在表上建立索引时,最重要的选择只是使用哪些列作为索引键。一旦你确定了聚集索引列(基于文中所示的三点建议),剩下的非聚集索引所带来的影响就交给SQL Server来处理吧。
  

小结
  非聚集索引包含了索引键列,包含列和书签。书签的值根据所在表是堆还是聚集索引既可以是RID也可以是聚集索引键。对于表上聚集索引的最好选择要基于文中所给的三点指南。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-81519-1-1.html 上篇帖子: SQL SERVER 查询性能优化——分析事务与锁(三) 下篇帖子: SQL SERVER 查询性能优化——分析事务与锁(一)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表