SQL Server 索引查找Index Seek 索引扫描 Index Scan与索引存储原理详解

本文主要是介绍SQL Server 索引查找Index Seek 索引扫描 Index Scan与索引存储原理详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

SQL Server索引查找 索引扫描 B-Tree与索引存储原理

索引查找的演示案例

聚集索引查找

索引查找(index seek)即查询条件内命中索引,直接接用主键匹配时触发聚集索引查找(Index Seek)

SELECT * FROM EMPLOYEES
WHERE id IN(10,100,1000,10000,100000,1000000)
SELECT * FROM EMPLOYEES WHERE id = 57864
SELECT * FROM EMPLOYEES WHERE id >10000 AND id < 1000000

以第一个查询为例,其执行计划见下:

可见用index seek时读取的行数和所有执行的实际行数都是6,命中率很高。

非聚集索引查找

命中非聚集索引的条件,再通过key lookup找到其它字段。详见“聚集索引的演示案例”里的“非聚集索引下WHERE查询”章节。

注:详见:

SQL Server 聚集索引 clustered index 非聚集索引Nonclustered Indexes键查找查找Key Lookup执行计划过程详解_数据科学汇集-CSDN博客

--在NAME字段上建立非聚集索引。
CREATE NONCLUSTERED INDEX IX_EMP_NAME ON EMPLOYEES(NAME)
-- 再次执行WHERE查询并含实际执行计划。
SELECT * FROM EMPLOYEES 
WHERE NAME = 'ABC 874000'

聚集索引应用场景概述

以下示例查询条件会用到索引查找:

id = 12000

score < 89

name = ’John’

name LIKE ’John%’

索引扫描的演示案例

索引扫描

详见“聚集索引的演示案例”里的“无索引下WHERE查询”章节。

SELECT * FROM EMPLOYEES 
WHERE NAME = 'ABC 874000'

这里因为没有索引,只能通过扫描聚集索引以索引扫描的方式获得数据。

索引扫描应用场景概述

以下示例查询条件会用到索引扫描:

ABS(id) = 12000

score+10< 89

name LIKE ’%john’

UPPER(name) = ’JOHN’

 覆盖索引的演示案例

建立索引时指定以include方式。

CREATE NONCLUSTERED INDEX IX_EMP_NAME2 ON EMPLOYEES(NAME) INCLUDE(email,dept)
SELECT * FROM EMPLOYEES 
WHERE NAME = 'ABC 874000'

数据存储介绍

物理存储方式

SQL Server里的数据在逻辑上以行列方式存储,在物理上以数据页的形式存储。一个数据页是SQL Server存储数据的基本单位,它有8k大小。当我们往表里插入时,数据会被存放在一系列的8k的数据页里。

数据实际存储示意

一系列的数据页以树的形式组织起来,具体见下图示意。这个树叫做B-Tree,索引B-Tree或者聚集索引结构。

上图B-tree里最底端的节点叫做数据页或者树的叶子节点,这些叶子节点里存放了表的数据。

数据页默认大小是8k,也即是说数据页能存放表的几行数据依赖于行数据的大小。

从示意图里可以看到第一个数据页存放1-200行数据,而第二页存放201-400依次类推。

B-tree的顶上的节点叫做根节点。

跟节点和叶子节点直接的叫做中间节点,根节点和中间节点存放索引行。

在每个索引行里都包含一个主键(如这里的Employeeid)、一个指向中间节点和叶子节点的指针。

B-Tree遍历示意

以通过员工号查询员工信息为例,我看下B-tree是怎么工作的。语句见下:

select * from Employees where EmployeeId = 1189

1 数据库引擎首先从数据的根节点开始遍历,因为我们的查询条件是Employeeid=1189,它属于索引行801-1200所在的范畴。

2 然后再从1里的子节点锁定Employeeid走右边的分支即属1001-1200的范畴。

3 最后从叶子节点对应的1001-1200的数据页里找到数据。

索引维护介绍

索引碎片

当索引中页面的逻辑顺序与数据文件中的物理顺序不匹配时,就会发生碎片。因为索引碎片会影响查询的性能,所以有时需要做索引重建。

1 索引碎片仅影响索引扫描和范围扫描的效率,对索引查找没有任何影响。

2 查询优化器不受碎片,不论是高碎片还是低碎片生成的计划都是相同的。

3 可以通过sys.dm_db_index_physical_stats 动态函数查看索引碎片情况。

SELECT a.object_id, a.index_id, name, avg_fragmentation_in_percent, fragment_count,
avg_fragment_size_in_pages
FROM sys.dm_db_index_physical_stats (DB_ID('ShenLiang2025'),
OBJECT_ID('EMPLOYEES'), NULL, NULL, NULL) AS a
JOIN sys.indexes AS b ON a.object_id = b.object_id AND a.index_id = b.index_id

索引重建

索引重建见如下语句:

--1重建指定索引
ALTER INDEX IX_EMP_NAME ON EMPLOYEES REBUILD;--2 重建表里所有索引
ALTER INDEX ALL ON dbo.EMPLOYEES REBUILD

这篇关于SQL Server 索引查找Index Seek 索引扫描 Index Scan与索引存储原理详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/438710

相关文章

Mysql数据库聚簇索引与非聚簇索引举例详解

《Mysql数据库聚簇索引与非聚簇索引举例详解》在MySQL中聚簇索引和非聚簇索引是两种常见的索引结构,它们的主要区别在于数据的存储方式和索引的组织方式,:本文主要介绍Mysql数据库聚簇索引与非... 目录前言一、核心概念与本质区别二、聚簇索引(Clustered Index)1. 实现原理(以 Inno

sqlserver、mysql、oracle、pgsql、sqlite五大关系数据库的对象名称和转义字符

《sqlserver、mysql、oracle、pgsql、sqlite五大关系数据库的对象名称和转义字符》:本文主要介绍sqlserver、mysql、oracle、pgsql、sqlite五大... 目录一、转义符1.1 oracle1.2 sqlserver1.3 PostgreSQL1.4 SQLi

使用python生成固定格式序号的方法详解

《使用python生成固定格式序号的方法详解》这篇文章主要为大家详细介绍了如何使用python生成固定格式序号,文中的示例代码讲解详细,具有一定的借鉴价值,有需要的小伙伴可以参考一下... 目录生成结果验证完整生成代码扩展说明1. 保存到文本文件2. 转换为jsON格式3. 处理特殊序号格式(如带圈数字)4

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

MyBatis常用XML语法详解

《MyBatis常用XML语法详解》文章介绍了MyBatis常用XML语法,包括结果映射、查询语句、插入语句、更新语句、删除语句、动态SQL标签以及ehcache.xml文件的使用,感兴趣的朋友跟随小... 目录1、定义结果映射2、查询语句3、插入语句4、更新语句5、删除语句6、动态 SQL 标签7、ehc

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置