当前位置: 首页 > news >正文

聚簇索引和非聚簇索引

 

一、聚簇索引(clustered indexes)的使用

 聚簇索引是一种对磁盘上实际数据重新组织以按指定的一个或多个列的值排序。由于聚簇索引的索引页面指针指向数据页面,所以使用聚簇索引查找数据几 乎总是比使用非聚簇索引快。每张表只能建一个聚簇索引,并且建聚簇索引需要至少相当该表120%的附加空间,以存放该表的副本和索引中间页。建立聚簇索引 的思想是:

1、大多数表都应该有聚簇索引或使用分区来降低对表尾页的竞争,在一个高事务的环境中,对最后一页的封锁严重影响系统的吞吐量。

2、在聚簇索引下,数据在物理上按顺序排在数据页上,重复值也排在一起,因而在那些包含范围检查(between、<、<=、& gt;、>=)或使用group by或order by的查询时,一旦找到具有范围中第一个键值的行,具有后续索引值的行保证物理上毗连在一起而不必进一步搜索,避免了大范围扫描,可以大大提高查询速度。

3、在一个频繁发生插入操作的表上建立聚簇索引时,不要建在具有单调上升值的列(如IDENTITY)上,否则会经常引起封锁冲突。

4、在聚簇索引中不要包含经常修改的列,因为码值修改后,数据行必须移动到新的位置。

5、选择聚簇索引应基于where子句和连接操作的类型。

聚簇索引的侯选列是:

1、主键列,该列在where子句中使用并且插入是随机的。

2、按范围存取的列,如pri_order > 100 and pri_order < 200。

3、在group by或order by中使用的列。

4、不经常修改的列。

5、在连接操作中使用的列。

二、非聚簇索引(nonclustered indexes)的使用

 SQLServer缺省情况下建立的索引是非聚簇索引,由于非聚簇索引不重新组织表中的数据,而是对每一行存储索引列值并用一个指针指向数据所在 的页面。换句话说非聚簇索引具有在索引结构和数据本身之间的一个额外级。一个表如果没有聚簇索引时,可有250个非聚簇索引。每个非聚簇索引提供访问数据 的不同排序顺序。在建立非聚簇索引时,要权衡索引对查询速度的加快与降低修改速度之间的利弊。另外,还要考虑这些问题:

1、索引需要使用多少空间。

2、合适的列是否稳定。

3、索引键是如何选择的,扫描效果是否更佳。

4、是否有许多重复值。

 对更新频繁的表来说,表上的非聚簇索引比聚簇索引和根本没有索引需要更多的额外开销。对移到新页的每一行而言,指向该数据的每个非聚簇索引的页级 行也必须更新,有时可能还需要索引页的分理。从一个页面删除数据的进程也会有类似的开销,另外,删除进程还必须把数据移到页面上部,以保证数据的连续性。 所以,建立非聚簇索引要非常慎重。非聚簇索引常被用在以下情况:

1、某列常用于集合函数(如Sum,....)。

2、某列常用于join,order by,group by。

3、查寻出的数据不超过表中数据量的20%。

三、覆盖索引(covering indexes)的使用

 覆盖索引是指那些索引项中包含查寻所需要的全部信息的非聚簇索引,这种索引之所以比较快也正是因为索引页中包含了查寻所必须的数据,不需去访问数 据页。如果非聚簇索引中包含结果数据,那么它的查询速度将快于聚簇索引。

 但是由于覆盖索引的索引项比较多,要占用比较大的空间。而且update操作会引起索引值改变。所以如果潜在的覆盖查询并不常用或不太关键,则覆 盖索引的增加反而会降低性能。

四、索引的选择技术

一般来说建立索引的思路是:

(1)、主键时常作为where子句的条件,应在表的主键列上建立聚簇索引,尤其当经常用它作为连接的时候。

(2)、有大量重复值且经常有范围查询和排序、分组发生的列,或者非常频繁地被访问的列,可考虑建立聚簇索引。

(3)、经常同时存取多列,且每列都含有重复值可考虑建立复合索引来覆盖一个或一组查询,并把查询引用最频繁的列作为前导列,如果可能尽量使关键查 询形成覆盖查询。

(4)、如果知道索引键的所有值都是唯一的,那么确保把索引定义成唯一索引。

(5)、在一个经常做插入操作的表上建索引时,使用fillfactor(填充因子)来减少页分裂,同时提高并发度降低死锁的发生。如果在只读表上 建索引,则可以把fillfactor置为100。

(6)、在选择索引键时,设法选择那些采用小数据类型的列作为键以使每个索引页能够容纳尽可能多的索引键和指针,通过这种方式,可使一个查询必须遍 历的索引页面降到最小。此外,尽可能地使用整数为键值,因为它能够提供比任何数据类型都快的访问速度。

五、索引的维护

 上面讲到,某些不合适的索引影响到SQLServer的性能,随着应用系统的运行,数据不断地发生变化,当数据变化达到某一个程度时将会影响到索 引的使用。这时需要用户自己来维护索引。索引的维护包括:

1、重建索引

 随着数据行的插入、删除和数据页的分裂,有些索引页可能只包含几页数据,另外应用在执行大块I/O的时候,重建非聚簇索引可以降低分片,维护大块 I/O的效率。重建索引实际上是重新组织B-树空间。在下面情况下需要重建索引:

(1)、数据和使用模式大幅度变化。

(2)、排序的顺序发生改变。

(3)、要进行大量插入操作或已经完成。

(4)、使用大块I/O的查询的磁盘读次数比预料的要多。

(5)、由于大量数据修改,使得数据页和索引页没有充分使用而导致空间的使用超出估算。

(6)、dbcc检查出索引有问题。

当重建聚簇索引时,这张表的所有非聚簇索引将被重建。

2、索引统计信息的更新

 当在一个包含数据的表上创建索引的时候,SQLServer会创建分布数据页来存放有关索引的两种统计信息:分布表和密度表。优化器利用这个页来 判断该索引对某个特定查询是否有用。但这个统计信息并不动态地重新计算。这意味着,当表的数据改变之后,统计信息有可能是过时的,从而影响优化器追求最有 工作的目标。因此,在下面情况下应该运行update statistics命令:

(1)、数据行的插入和删除修改了数据的分布。

(2)、对用truncate table删除数据的表上增加数据行。

(3)、修改索引列的值。

六、结束语

 实践表明,不恰当的索引不但于事无补,反而会降低系统的执行性能。因为大量的索引在插入、修改和删除操作时比没有索引花费更多的系统时间。例如下 面情况下建立的索引是不恰当的:

1、在查询中很少或从不引用的列不会受益于索引,因为索引很少或从来不必搜索基于这些列的行。

2、只有两个或三个值的列,如男性和女性(是或否),从不会从索引中得到好处。

 另外,鉴于索引加快了查询速度,但减慢了数据更新速度的特点。可通过在一个段上建表,而在另一个段上建其非聚簇索引,而这两段分别在单独的物理设 备上来改善操作性能。

相关文章:

  • 聚簇索引与非聚簇索引的区别以及SQL Server查询优化技术
  • 排序算法大荟萃——希尔(Shell)排序算法
  • Java内存泄露的理解与解决
  • 大冰--寻人启事--one
  • Java反射访问私有变量和私有方法
  • 电源开关IC
  • Java中sleep和wait的区别
  • iOS的一些面试题分析总结(1)
  • sql中的group by
  • java的finally语句
  • 各种编程语言变量的数据类型
  • java解惑你知多少(一)
  • 《Entity Framework 6 Recipes》中文翻译系列 (7) -----第二章 实体数据建模基础之拆分实体到多表以及拆分表到多实体...
  • java解惑你知多少(二)
  • lnmp的使用
  • 【刷算法】从上往下打印二叉树
  • 07.Android之多媒体问题
  • 2019.2.20 c++ 知识梳理
  • Android Studio:GIT提交项目到远程仓库
  • ES6核心特性
  • iOS编译提示和导航提示
  • IOS评论框不贴底(ios12新bug)
  • Python语法速览与机器学习开发环境搭建
  • React 快速上手 - 07 前端路由 react-router
  • Unix命令
  • 提醒我喝水chrome插件开发指南
  • 阿里云移动端播放器高级功能介绍
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • $L^p$ 调和函数恒为零
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • %3cscript放入php,跟bWAPP学WEB安全(PHP代码)--XSS跨站脚本攻击
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (1)常见O(n^2)排序算法解析
  • (3)llvm ir转换过程
  • (a /b)*c的值
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (Mirage系列之二)VMware Horizon Mirage的经典用户用例及真实案例分析
  • (附源码)ssm高校实验室 毕业设计 800008
  • (附源码)ssm高校运动会管理系统 毕业设计 020419
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (简单) HDU 2612 Find a way,BFS。
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (十一)c52学习之旅-动态数码管
  • (转)我也是一只IT小小鸟
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
  • .net Signalr 使用笔记
  • .NET 药厂业务系统 CPU爆高分析
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .NET/C# 检测电脑上安装的 .NET Framework 的版本
  • .NET分布式缓存Memcached从入门到实战
  • .net生成的类,跨工程调用显示注释
  • .NET中GET与SET的用法
  • [2015][note]基于薄向列液晶层的可调谐THz fishnet超材料快速开关——