T-SQL查询进阶:理解SQL Server中索引的概念,原理以及其他

简介

在SQL Server中,索引是一种增强式的存在,这意味着,即使没有索引,SQL Server仍然可以实现应有的功能。但索引可以在大多数情况下大大提升查询性能,在OLAP中尤其明显.要完全理解索引的概念,需要了解大量原理性的知识,包括B树,堆,数据库页,区,填充因子,碎片,文件组等等一系列相关知识,这些知识写一本小书也不为过。所以本文并不会深入讨论这些主题。

索引是什么

索引是对数据库表中一列或多列的值进行排序的一种结构,使用索引可快速访问数据库表中的特定信息。

精简来说,索引是一种结构.在SQL Server中,索引和表(这里指的是加了聚集索引的表)的存储结构是一样的,都是B树,B树是一种用于查找的平衡多叉树.理解B树的概念如下图:

理解为什么使用B树作为索引和表(有聚集索引)的结构,首先需要理解SQL Server存储数据的原理.

在SQL SERVER中,存储的单位最小是页(PAGE),页是不可再分的。就像细胞是生物学中不可再分的,或是原子是化学中不可再分的最小单位一样.这意味着,SQL SERVER对于页的读取,要么整个读取,要么完全不读取,没有折中.

在数据库检索来说,对于磁盘IO扫描是最消耗时间的.因为磁盘扫描涉及很多物理特性,这些是相当消耗时间的。所以B树设计的初衷是为了减少对于磁盘的扫描次数。如果一个表或索引没有使用B树(对于没有聚集索引的表是使用堆heap存储),那么查找一个数据,需要在整个表包含的数据库页中全盘扫描。这无疑会大大加重IO负担.而在SQL SERVER中使用B树进行存储,则仅仅需要将B树的根节点存入内存,经过几次查找后就可以找到存放所需数据的被叶子节点包含的页!进而避免的全盘扫描从而提高了性能.

下面,通过一个例子来证明:

在SQL SERVER中,表上如果没有建立聚集索引,则是按照堆(HEAP)存放的,假设我有这样一张表:

现在这张表上没有任何索引,也就是以堆存放,我通过在其上加上聚集索引(以B树存放)来展现对IO的减少:

时间: 2025-01-01 00:09:32

T-SQL查询进阶:理解SQL Server中索引的概念,原理以及其他的相关文章

图片-qiushou求SQL查询语句问题, SQL语句忘记怎么写了

问题描述 qiushou求SQL查询语句问题, SQL语句忘记怎么写了 第一列是-主键-地区-销售人员-销售总额, 请问查询-每个地区销售金额最少的人是谁 解决方案 select * from ( select rank() over(partition by region order by total) as rid ,orderid,region,sales,total from salesorder ) t where t.rid = 1 解决方案二: select * from sale

深入理解JavaScript编程中的原型概念

  这篇文章主要介绍了深入理解JavaScript编程中的原型概念,包括prototype属性的使用等一些相关知识,需要的朋友可以参考下 JavaScript 的原型对象总是让人纠结.即使是经验丰富的JavaScript专家甚至其作者,经常对这一概念给出很有限的解释.我相信问题来自于我们对原型最早的认识.原型总是与new, constructor 以及令人困惑的prototype属性紧密联系.事实上,原型是一个相当简单的概念.为了更好地理解它,我们需要忘记我们所'学到'的构造原型,然后,追本溯源

SQL Server中索引使用及维护

server|索引 在应用系统中,尤其在联机事务处理系统中,对数据查询及处理速度已成为衡量应用系统成败的标准.而采用索引来加快数据处理速度也成为广大数据库用户所接受的优化方法. 在良好的数据库设计基础上,能有效地使用索引是SQL Server取得高性能的基础,SQL Server采用基于代价的优化模型,它对每一个提交的有关表的查询,决定是否使用索引或用哪一个索引.因为查询执行的大部分开销是磁盘I/O,使用索引 提高性能的一个主要目标是避免全表扫描,因为全表扫描需要从磁盘上读表的每一个数据页,如果

SQL Server中索引使用及维护简介

在应用系统中,尤其在联机事务处理系统中,对数据查询及处理速度已成为衡量应用系统成败的标准.而采用索引来加快数据处理速度也成为广大数据库用户所接受的优化方法. 在良好的数据库设计基础上,能有效地使用索引是SQL Server取得高性能的基础,SQL Server采用基于代价的优化模型,它对每一个提交的有关表的查询,决定是否使用索引或用哪一个索引.因为查询执行的大部分开销是磁盘I/O,使用索引提高性能的一个主要目标是避免全表扫描,因为全表扫描需要从磁盘上读表的每一个数据页,如果有索引指向数据值,则查

关于SQL Server中的死锁详解介绍(1/3)

 一些基础知识     要理解SQL Server中的死锁,更好的方式是通过类比从更大的面理解死锁.比如说一个经典的例子就是汽车(主体)对于道路(资源)的征用,如图1所示. 对于死锁的直观理解      在图1的例子中,每队汽车都占有一条道路,但都需要另外一队汽车所占有的另一条道路,因此互相阻塞,谁都无法前行,因此造成了死锁.由这个简单的例子可以看出,发生死锁需要四个必要条件,如下: 1)互斥条件:     主体对于资源是独占的,图1中每条汽车道只能跑一队汽车,不能跑第二队.  2)请求和等待条

SQL Server中的锁的简单学习

原文:SQL Server中的锁的简单学习 简介     在SQL Server中,每一个查询都会找到最短路径实现自己的目标.如果数据库只接受一个连接一次只执行一个查询.那么查询当然是要多快好省的完成工作.但对于大多数数据库来说是需要同时处理多个查询的.这些查询并不会像绅士那样排队等待执行,而是会找最短的路径执行.因此,就像十字路口需要一个红绿灯那样,SQL Server也需要一个红绿灯来告诉查询:什么时候走,什么时候不可以走.这个红绿灯就是锁.     图1.查询可不会像绅士们那样按照次序进行

SQL Server-聚焦深入理解动态SQL查询(三十二)

前言 之前有园友一直关注着我快点出SQL Server性能优化系列,博主我也对性能优化系列也有点小期待,本来打算利用周末写死锁以及避免死锁系列的接着进入SQL Server优化系列,但是在工作中长时间都是利用EF来操作SQL,不免对写SQL语句有些生疏,在某些场景下还是只能利用底层的SQL语句或者写存储过程来实现,很久没写存储过程都忘记怎么写了,所以本节穿插动态SQL查询的文章,别着急,博主说过不会烂尾,博主再忙也会抽空将整个SQL Server系列梳理完毕,那样的话,无论对初级还是中级者都可以

SQL SERVER中一些常见性能问题的总结

server|问题|性能 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:select id from t where num is null可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:select id from t where num=0 3.应尽量避免在 where 子句中使用!=或<>

SQL Server中的Processor Affinity

SQL Server通常都运行在多处理器的服务器上,这一点在现在尤为普遍.原因是多内核的处理器越来越普及. 那么,在多处理器环境下,Windows操作系统(事实上是从2000开始的)通常都会将进程任务放在一个队伍里面,然后让这些处理任务依次去占有处理器进行计算. 这样做的好处就是每个计算任务都可以获得近似于平均的处理资源,尽管无法保证一个处理任务每次都能拿到同一个处理器.这就像嘉年华我们重复排队参加一个刺激的项目(比如说自由落体,事实上我从来不参加这种项目),每个人上去一轮,并不能保证每次都能做