SQL Server数据库索引的基础知识
一、理解索引的结构
索引在数据库中的作用类似于目录在书籍中的作用,用来提高查找信息的速度。使用索引查找数据,无需对整表进行扫描,可以快速找到所需数据。微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引、簇集索引)和非聚集索引(nonclustered index,也称非聚类索引、非簇集索引)。
SQL Server 中数据存储的基本单位是页(Page)。数据库中的数据文件(.mdf 或 .ndf)分配的磁盘空间可以从逻辑上划分成页(从 0 到 n 连续编号)。磁盘 I/O 操作在页级执行。也就是说,SQL Server 每次读取或写入数据的最少数据单位是数据页。
下面我们先简单的了解一下索引的体系结构:
1. 聚集索引结构
在 SQL Server 中,索引是按 B 树结构进行组织的。
聚集索引单个分区中的结构:
--建立UserAddDate聚集索引 Create CLUSTERED INDEX [IX_AddDate] ON [User] ( [AddDate] ASC )
聚集索引(Clustered Index)特点
聚集索引的叶节点就是实际的数据页
聚集索引中的排序顺序仅仅表示数据页链在逻辑上是有序的。而不是按照顺序物理的存储在磁盘上
行的物理位置和行在索引中的位置是相同的
每个表只能有一个聚集索引
聚集索引的平均大小大约为表大小的5%左右
2. 非聚集索引结构
非聚集索引与聚集索引具有相同的 B 树结构,它们之间的显著差别在于以下两点:
1. 基础表的数据行不按非聚集键的顺序排序和存储。
2. 非聚集索引的叶层是由索引页而不是由数据页组成。
下图示意了单个分区中的非聚集索引结构:
包含列的索引
通过将包含列(称为非键列)添加到索引的叶级,可以扩展非聚集索引的功能。键列存储在非聚集索引的所有级别,而非键列仅存储在叶级别。
下面举个简单的例子来说明一下聚集索引和非聚集索引的区别:
我们有一本汉语字典,可以把它的正文本身看做是一个聚集索引,它是按照汉字拼音的开头字母排序的,不再需要查找其他目录。当遇到不认识的字时,需要结合“部首目录”和“检字表”, 先找到目录中的结果,然后再翻到您所需要的页码。通过这种方法查到的目录中字的排序并不是真正的正文的排序方法。把这种看做是一个非聚集索引。
另外,请注意每个表只能有一个聚集索引。
--建立UserAddDate非聚集索引 Create NONCLUSTERED INDEX [IX_AddDate] ON [User] ( [AddDate] ASC )
非聚集索引 (Unclustered Index) 特点
非聚集索引的页,不是数据,而是指向数据页的页。
若未指定索引类型,则默认为非聚集索引。
叶节点页的次序和表的物理存储次序不同
每个表最多可以有249个非聚集索引
在非聚集索引创建之前创建聚集索引(否则会引发索引重建)
二、选择建立哪种索引
1. 何时创建聚集索引更能提高性能
Clustered Index会提高大多数table的性能,尤其是当它满足以下条件时:
独特, 狭窄, 持续增长的,最好是只向上增加。例如:
Identity
Date, identity
GUID (only when using newsequentialid() function)
2. 非聚集索引提高性能的方法
非聚集索引由于B树的节点不是具体数据页,有时候由于这个原因,会导致非聚集索引甚至不如表遍历来的快。但是,非聚集索引有个特性,如果你要查询的内容,在非聚集索引中以及被覆盖到了,则不需要继续到聚集索引,或者RID(heap结构中的行标识符)中去寻找数据了,这时候就可以很大的提高性能,这就是覆盖面(Covering) 的问题。
由于聚集索引叶子节点就是具体数据,所以聚集索引的覆盖率是100%, 通过提高覆盖面来提高性能的问题也就只有非聚集索引(Nonclustered Indexes)才存在。
当查询中所有的columns都包括在index上时,我们说这 index covers the query. Columns的顺序在此不重要(Select 时候的顺序不重要,但是Index 建立的顺序可得小心了)。
在 SQL Server 2005 中,为了提高这种 Covering 带来的好处,甚至可以通过将非键列添加到非聚集索引的叶级别来扩展非聚集索引的功能。
补充:只有查询在具有高度选择性的情况下,非聚集索引才有优势。
三、使用聚集索引或非聚集索引的场景 (注:优先级依次为推荐,应,不应)
四、主键和聚集索引的比较
以下是一些大众点评网中测试使用的示例:
CHECKPOINT
DBCC DropCLEANBUFFERS
SET STATISTICS IO ON
declare @d datetime
set @d=getdate()
Select * FROM User Where AddDate>'2008-06-01' AND AddDate<'2008-06-10'
select [语句执行花费时间(毫秒)]=datediff(ms,@d,getdate())
--(45077 行受影响)
--表'User'。扫描计数1,逻辑读取1103 次,物理读取2 次,预读1090 次,lob 逻辑读取0 次,
lob 物理读取0 次,lob 预读0 次。
--2543
CHECKPOINT
DBCC DropCLEANBUFFERS
SET STATISTICS IO ON
declare @d datetime
set @d=getdate()
Select * FROM User WITH (INDEX=IX_AddDate) Where AddDate>'2008-06-01' AND AddDate<'2008-06-10'
select [语句执行花费时间(毫秒)]=datediff(ms,@d,getdate())
--(45077 行受影响)
--表'User'。扫描计数1,逻辑读取45165 次,物理读取133 次,预读141 次,lob 逻辑读取0 次,
lob 物理读取0 次,lob 预读0 次。
--3860
五、使用索引的代价
索引需要占用数据表以外的物理存储空间
创建索引和维护索引要花费一定的时间
当对表进行更新操作时,索引需要被重建,这样降低了数据的维护速度。
SQL Server数据库索引的基础知识相关推荐
- SQL Server之游标的基础知识
什么是游标: 游标是可以在结果集中上下游动的指针. 游标的作用: --允许定位到结果集中的特定行. --从结果集的当前位置检索一行或多行数据. --支持对结果集中当前位置的行进行修改. 注意:游标虽然 ...
- Python连接SQL Server数据库 - pymssql使用基础
连接数据库 pymssql连接数据库的方式和使用sqlite的方式基本相同: 使用connect创建连接对象 connect.cursor创建游标对象,SQL语句的执行基本都在游标上进行 cursor ...
- SQL Server 数据库索引的优缺点及原理
什么是索引: 索引就像是书的目录,是与表或视图关联的磁盘上结构,可以加快从表或视图中检索行的速度.索引中包含由表或视图中的一列或多列生成的键.这些键存储在一个结构(BTree)中,使SQL可以快速有效 ...
- SQL server 数据库——T-SQL语句基础
T-SQL语句基础 1.创建数据库:create datebase 数据库名 2.删除数据库:delete datebase 数据库名 3.注释:/*一段 */ 一行 -- 4. ...
- python 使用pymssql连接sql server数据库
Python连接SQL Server数据库 - pymssql使用基础 ----原文地址:http://www.cnblogs.com/baiyangcao/p/pymssql_basic.html ...
- SQL Server 数据库之视图(三)
视图(三) 1. 概述 2. 在视图中插入数据记录 3. 在视图中修改数据记录 4. 在视图中删除数据记录 1. 概述 由于视图是一张虚表,对视图的更新最终实际上是转换成对视图的基本表的更新,因此可通 ...
- 数据库应用程序开发基础篇—— .NET中SQL Server数据库的操作C#篇之一
数据库应用程序开发基础篇-- .NET中SQL Server数据库的操作C#篇之一 写在前面:前面介绍了数据库系统的基本概念,SQl语句基本使用方法,接下来通过学习具体语言和具体数据库结合的应用开发来 ...
- c井语言和SQL第一章上机1,第一章 SQL Server 数据库基础复习内容(上机)
上机课程总目标 在本学期中,将模拟开发一套学员信息管理系统,用来管理学员的个人基本资料,老师资料,学生成绩,课程信息等教学相关内容,以实现学校的信息自动化,提高工作效率. 该系统包括学生档案管理.学生 ...
- 1 SQL server数据库基础
SQL server数据库基础 一 数据库简介 1数据库的基本概念 1)数据 ·描述事物的符号记录称为数据(Data),包括数字.文字.图像.声音等.以"记录"的形式按统一格式进行 ...
最新文章
- 改写了一个shell写的cdn节点测试代码
- java 进程通信框架,MediatR-进程内的消息通信框架
- 有关eigen库的一些基本使用方法
- 【 Linux 】单台服务器上并发TCP连接数(转)
- java socket绑定ip_ServerSocket 默认邦定IP
- boost::units模块单位/数量操作和转换的测试程序
- 把Sublime Text 2打造成一个轻量级Python的IDE
- 最为奇怪的程序语言的特性
- 第九届中国开源黑客松活动将于2019年4月18日-4月20日,在深圳举办
- 视频水印怎么去除?超简单 千万不要错过
- ThinkPad E431 Bluetooth驱动
- 小米路由固件中lua文件反编译
- R 计算变量之间的相关性
- 2023学年持IB成绩申请NTU入学流程指南
- 最先进的实体对齐方法的实验研究综述 An Experimental Study of State-of-the-Art Entity Alignment Approaches
- 用苹果手机计算机程序二,两台iPhone怎么互传软件 苹果手机互传应用的3个小技巧...
- ppt文件服务器权限破解,怎么解开PPT文档的权限保护?
- 2023年还在问前端怎么学?一份前端学习指南
- 大数据处理问题及解决方法
- JAVA WEB之XSS防御工具类代码示例
热门文章
- 预编译头文件来自编译器的早期版本,或者预编译头为 C++ 而在 C 中使用它(或相反)
- halcon测试一张图片是否过曝或过暗
- clover引导mbr安装黑苹果_安装黑苹果记录(一)
- php 完美分页,php完美分页类程序
- Windows环境下Code::Blocks中成功配置MySQL Connector/C连接MySQL数据库
- Vue.js + Nuxt.js 项目中使用 Vee-validate 表单校验
- x86汇编语言-从实模式到保护模式----第五章
- 使用泛型解决之前的问题
- 程序员跳槽全攻略pdf
- Heap 3214 LIS题解