介绍

索引在 SQL Server 查询性能中起着至关重要的作用。考虑一个拥有数千本书的图书馆。

您想搜索标题中包含关键字“冒险”的特定书籍。图书馆里的书杂乱无章。

  • 您需要从书架上取下每本书,阅读它,如果它不满足您的要求,则将其放回原处
  • 在大型图书馆中,您可能需要几天时间才能找到一本书

假设这个图书馆是一个 SQL 表,所以在 SQL Server 术语中,扫描图书馆中的所有书籍称为表(索引)扫描。

假设您找到了两本关于“adventure”关键字的书,现在您有兴趣在该书中搜索另一个关键字。每本书包含 2,000 页。

您是否可以在不阅读书籍的情况下在书中搜索特定关键字?

在一本书中,我们使用索引来定位您可以找到关键字的页面。在 SQL Server 术语中,我们称其为索引查找操作。

我们可以按照下图可视化表扫描和索引查找操作:

我们在 SQL Server 中主要有两种类型的索引:

  • 聚集索引(Cluster Index)
  • 非聚集索引(NonClustered Index)

SQL Server 中的聚集索引(Clustered Index)概述

SQL Server 在 B 树结构中创建索引。SQL Server 以这种结构组织数据以快速搜索所需的数据,而不是进行表扫描。

如下图所示,我们在一个 B 树结构索引中有三个层次:

根节点(Root Node)
它是一个顶级节点,由一个指向中间索引页或叶节点(数据页)的指针组成。

中间节点(Intermediate Node)
它由索引键值以及指向下一个中间级别页面或叶数据页面的指针组成。它取决于中间级别数的数据大小。

叶节点(Leaf Node)
它由实际数据页组成。将此视为实际数据存储在 SQL Server 中的聚集索引中的一个点。

让我们为我们的图书馆示例想象这个 b 树。假设我们图书馆有 10,000 本书,并在图书馆表的 bookid 列上创建了聚集索引(CI)

如上图所示,我们在 library 表的bookid列上定义了索引。现在,如果我们想检索一个特定的书,比如 bookid 7579,SQL Server 会读取以下页面:

  • 根节点:根页告诉SQL Server,5001到10000 的中间节点的指针
  • 中间节点: SQL Server读取中间索引页并获取叶节点中实际数据页的指针
  • 叶节点: SQL Server 根据我们的要求读取叶节点中的数据页

如前所述,SQL Server 读取索引页并返回信息。此过程称为索引查找(Index Seek)。在某些情况下,SQL Server 读取所有叶级数据页。它被称为索引扫描(Index Scan)。毫无疑问,索引查找比索引扫描更快。

让我们创建一个测试表并插入几条数据:

CREATE TABLE dbo.bookstore
(book_id   INT NOT NULL, book_name VARCHAR(100)
);
Insert into dbo.bookstore values(1,'Learn ABC of SQL Server')
Insert into dbo.bookstore values(2,'Advanced troubleshooting step SQL Server')

我们在表上没有任何索引。没有**聚集索引(CI)**的表称为堆表(Heap Table)。

然后我们再给测试表创建一个聚集索引:

CREATE UNIQUE CLUSTERED INDEX [IX_bookstore_clustered] ON [dbo].[bookstore]
([book_id] ASC
);

检查聚集索引级别

我们可以使用 DMV sys.dm_db_index_physical_stats来检查索引碎片级别,CI 的索引级别。在表中插入几条记录并执行以下查询:

SELECT  avg_page_space_used_in_percent, avg_fragmentation_in_percent, index_level, record_count, page_count, fragment_count, avg_record_size_in_bytes
FROM sys.dm_db_index_physical_stats(DB_ID('SQLShack'), OBJECT_ID('bookstore'), NULL, NULL, 'DETAILED');
GO

在下面的屏幕截图中,我们有两个级别的索引:

查看带有聚集索引的查询的执行计划

让我们执行以下查询并查看实际执行计划:

SELECT *
INTO books_1
FROM bookstore;

SQL Server 使用索引查找从书店表中检索记录:

让我们使用以下查询创建一个备份表:

SELECT *
INTO books_1
FROM bookstore;

此备份表与主表具有相似的结构和数据。唯一的区别是备份表没有任何索引,而我们的主表在books_ID列上包含 CI 。

让我们在单独的窗口中执行以下查询并比较执行计划:

SELECT *
FROM book_1
WHERE book_ID = 10000;SELECT *
FROM bookstore
WHERE book_ID = 10000;

在上面的屏幕截图中,请注意以下差异。我们可以快速算出堆和带有聚集索引的表的性能对比:

堆表(无索引) 在查询中包含了聚集索引的表
逻辑运算 Table Scan Cluster Index
逻辑读取 1820 3
物理读取 1688 0
估计要读取的行数 734725 0
估计操作成本 2.15889 0.0032831
估计IO成本 1.35061 0.003125
估计CPU成本 0.808276 0.0001581
读取的行数 1688 0

结论

在本文中,我们探讨了 SQL Server 中的聚集索引以及创建它的 t-SQL 方法。我们还学习了堆和 CI 键表之间的性能比较。您应该根据更好的查询性能要求定义 CI。

原文地址

SQL Server索引概要(1)-聚集索引(Clustered Index)相关推荐

  1. SQL Server索引概要(3)-聚集索引和非聚集索引的区别

    索引用于加速 SQL Server 中的查询过程,从而提高性能.它们类似于教科书索引.在教科书中,如果您需要转到特定章节,请转到索引,找到该章节的页码并直接转到该页面.如果没有索引,查找所需章节的过程 ...

  2. SQL Server 堆heap 非聚集索引 Nonclustered index 行号键查找RID loopup结合执行计划过程详解

    SQL Server 堆型数据与执行计划使用案例 索引的相关术语 1 堆(Heap)是一种没有指定排序的数据结构,通俗的理解堆就像是按照顺序排放的杂物.在数据库里也即是对应没有聚集索引. 2 聚集索引 ...

  3. sql server 创建唯一性非聚集索引语句_数据库专题—索引原理

    深入浅出数据库索引原理 参见:https://www.cnblogs.com/aspwebchh/p/6652855.html 1.为什么给表加上主键? 1.平时创建表的时候,都会给表加上主键.如果没 ...

  4. sql查询初学者指南_面向初学者SQL Server查询执行计划–聚集索引运算符

    sql查询初学者指南 We have discussed how to created estimated execution plans and actual execution plans in ...

  5. sql聚集索引和非聚集索引_SQL Server中非聚集索引概述

    sql聚集索引和非聚集索引 This article gives an introduction of the non-clustered index in SQL Server using exam ...

  6. [转]SQL Server 索引基础知识(2)----聚集索引,非聚集索引

    SQL Server 索引基础知识(2)----聚集索引,非聚集索引 [来自]http://blog.joycode.com/ghj/archive/2008/01/02/113291.aspx 由于 ...

  7. SQL Server 解读【已分区索引的特殊指导原则】(3) - 非聚集索引分区

    一.前言 在MSDN上看到一篇关于SQL Server 表分区的文档:已分区索引的特殊指导原则,如果你对表分区没有实战经验的话是比较难理解文档里面描述的意思.这里我就里面的一些概念进行讲解,方便大家的 ...

  8. SQL Server的聚集索引和非聚集索引

    微软的SQL SERVER提供了两种索引:聚集索引(clustered index,也称聚类索引.簇集索引)和非聚集索引(nonclustered index,也称非聚类索引.非簇集索引)-- (一) ...

  9. [转]聚集索引和非聚集索引(sql server索引结构及其使用)

    聚集索引和非聚集索引(sql server索引结构及其使用) [来自]http://www.cnblogs.com/xinqqing83/archive/2006/10/31/545747.html ...

最新文章

  1. 云原生架构演进与企业上云
  2. 2021春季学期-创新设计与实践-Lesson2
  3. 快速排序(quick sort) C++
  4. Collections集合工具类的方法_addAllshuffle
  5. oracle恢复drop建的表首次,案例:Oracle dul数据挖掘 没有备份情况下非常规恢复drop删除的数据表...
  6. RouterModule.forRoot() called twice
  7. webstrom命名改名 命令
  8. 关于英特尔物联网你不可不知的10个最新动向
  9. 第13天:页面布局实例-博雅主页
  10. 基于STM32的卧室智慧监测系统
  11. lammps建模技巧:msi2lmp转换data文件结构错位解决办法
  12. 升级mac系统正在计算机,USB对拷线在苹果Mac系统的升级说明
  13. 操作系统-进程互斥的软件实现方法
  14. html网页设计小作业(个人主页)
  15. 网络爬虫-腾讯支付encrypt_msg参数逆向
  16. python注释快捷键alt_python快捷键的使用【摘抄】
  17. 【费用流】loj#545. 「LibreOJ β Round #7」小埋与游乐场
  18. 免费的网页原型制作工具
  19. 数据库从入门到删库跑路(二) - - PL/SQL
  20. openlayers3开发教程_开始

热门文章

  1. iOS开发笔记之二十二——归档Archiver(二)
  2. windows可以ping通网络但是浏览器却不能上网
  3. 关于3D建模师的前途,认真告诉你,技术上来了真的不愁薪资(下)
  4. 结构体类型和变量定义及基本操作
  5. android如何在华为市场发布应用
  6. “Hello World!“”团队第七周召开的第三次会议
  7. 人工智能之数学基础----指数函数和对数函数
  8. numpy ravel、squeeze函数
  9. SpringBoor入门
  10. 不支持AVX指令集的电脑安装tensorflow