T-SQL查询优化乱弹

以下是我整理的一些在SQL Server上实现高效查询的技巧和提示。经验之谈,不妥之处请大家指正。


1. 关于索引


谈数据库查询优化必然要讲索引。索引是个大话题。想要尽可能提高数据库系统的性能,设计良好的索引,必然要深入了解索引的结构,这个可以专门开一个话题来讨论(在《SQL Server 2005技术内幕:存储引擎》一书中这个话题是用专门的一章来讲的)。这次我们主要谈查询技巧,对索引只要有一个基本的理解即可。

举个例子来理解索引:
以一本汉语字典为例,字典好比一个表,表中的每个字及其拼音、解释可以理解为字段,每个字即一行记录;字典中的字是按照拼音和笔划顺序排列的,因此拼音和笔划即字典表的聚集索引键(复合键)。字典前面的目录是非聚集索引,包括拼音索引、部首索引、笔划索引、四角号码索引等等。
由此:
一、聚集索引只能有一个 。因为字典表中的字(记录)不可能既按拼音和笔划排序又按部首排序。但聚集索引并非只能建在拼音和笔划上,比如四号号码字典或是古时的辞典。
二、非聚集索引可以有多个 。非聚集索引查到的只是一个指向记录存放位置的页码(这只是举例,SQLServer的具体实现略有不同)。
三、在已经被索引覆盖的字段上建索引是一种不必要的浪费 。比如拼音已经被聚集索引覆盖了,前面目录中的非聚集拼音索引则是多余。(这一点后面详述)
(以下两条涉及索引的结构和关系模型的概念,可以不深究)
四、如果索引键不是唯一的,则索引结构中会引入一个附加属性来保证唯一排序 。比如在部首索引中,相同部首之下的字会按笔划排序。
五、主键与聚集索引键并不等价 。前者是一个数据模型的抽象概念,后者是一个数据库的物理结构。字典表的主键是字和拼音的组合键,它唯一地决定一个确定读音的汉字,这也表示字典表中的一条记录。拼音和笔划的组合聚集索引键只是字典表的物理存储方式。很多时候聚集索引键与主键是相同的,但这并不必然。

理解了索引的结构,我们就很容易明白索引对于高效查询的重要性。一个没有索引的表在物理上是一个堆(heap),即一堆无序的数据,比如一个小学生的练字本。对于小表,堆扫描也足够快,比如在小学生的练字本上找一个字,我们只能将整个表遍历一遍,这不困难;但不能想象每次查字典都要将整本字典遍历一遍。所以,在大表上通常要根据查询需要建合适的索引。
如果要查一个知道读音的字,这时可以使用聚集索引:比如“牛”字的拼音是niu2(2表示二声),我可以直接翻字典的中部(N在字母表的中部),然后根据翻到的字母去逼近目标值niu2,如果niu2这个拼音的字有多个,我可以再根据聚集索引键的第二个字段笔划顺序去找“牛”字,当然这时候通常已经定位到了一个数据页(真的是一页),扫描也是很快的,以至我们通常不会意识到使用聚集索引键的第二个字段。这便是Clustered Index Seek。
然而很多人根据读音查一个字时通常习惯于先在拼音目录找到这个字的页码再去翻相应的页,因为小学语文教字典使用方法时是这么教的。这种方法和根据部首查一个字一样,是No-clustered Index Seek + Table Lookup。因为拼音目录的页数少,查找起来会比聚集索引查找快一些,但这种方法后面要多加一步表查找,总耗时可能比较大。这样看来,学校教的这种查字典方法就好比加了一个强制使用拼音索引的查询提示(hint),让数据库引擎放弃聚集索引不用而优先使用拼音字段上的非聚集索引。

在实际的数据库中,索引发挥作用

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值