资讯专栏INFORMATION COLUMN

SQL Server索引简介:SQL Server索引进阶 Level 1

Lionad-Morotar / 2498人阅读

摘要:此外,非聚簇索引条目具有一些仅内部使用的头信息,并且可能包含一些可选信息。这两个都将在以后的层面上予以涵盖此时对于非聚簇索引的理解也不重要。

作者:David Durant,2014/11/05(首次发布:2011/02/17)

关于系列

本文属于进阶系列的:Stairway to SQL Server Indexes

索引是数据库设计的基础,并告诉开发人员使用数据库大量关于设计人员的意图。不幸的是,当性能问题出现时,索引通常被添加为事后的想法。最后这一系列简单的文章,应该能使任何数据库专业人员快速的“加快速度”。


此第一级引入SQL Server索引:数据库对象,使SQL Server能够在最短时间内查找和/或修改所请求的数据,使用最少的系统资源实现最大性能。良好的索引还将允许SQL Server实现最大的并发性,以便一个用户运行的查询对其他人运行的查询几乎没有影响。最后,索引提供了一种实现数据完整性的有效方法,通过在创建唯一索引时保证键值的唯一性。这个级别是一个介绍;它涵盖了概念和用法,但将物理细节留给了更高的层次。

对数据库开发人员的透彻理解对于数据库开发人员来说非常重要,其中一个原因来自于所有其他原因:当SQL Server从客户端到达的请求时,SQL Server只有两种可能的方式来访问所请求的行:

它可以扫描包含数据的表中的每一行,从第一行开始,并继续到最后一行,检查每一行以查看它是否符合请求标准。

或者,如果有益的索引可用,则可以使用索引来定位所请求的数据。
第一个选项始终可用于SQL Server。第二个选项只有在您指示SQL Server创建有益的索引时才可用,但可以显着提高性能,因为我们稍后会在此级别进行说明。

因为索引具有与它们相关联的开销(它们占用空间并且必须与表保持同步),所以它们不是SQL Server所必需的。完全没有索引的数据库是可能的。它可能会执行得很差,一定会有数据完整性问题,但SQL Server将允许它。

但是,这不是我们想要的。我们都希望数据库运行良好,具有数据完整性,同时将索引开销降至最低。这个水平将使我们开始实现这一目标。

样例数据库

在这个楼梯中,我们将用例子来说明关键概念。 这些示例基于Microsoft AdventureWorks示例数据库。 我们专注于销售订单功能。 五个表将给我们很好的组合事务和非交易数据; 客户,SalesPerson,产品,SalesOrderHeader和SalesOrderDetail。 为了保持重点,我们使用一列子集。

AdventureWorks正常化,所以销售人员信息被分为三个表格: 销售人员,员工和联系人。 对于一些例子,我们将它们视为单个表。 我们将使用的完整的表,以及它们之间的关系,如图1.1所示。

图1.1:将在此楼梯中使用的AdventureWorks表

注意:
此楼梯级别中显示的所有TSQL代码可以与文章一起下载(请参阅本文底部的链接)

什么是索引?

我们开始对索引的研究,一个简短的故事,一个使用一个旧的而且被证明的技术,我们在本文中将引用索引的基本概念。

你离开你的房子跑几个差事。当你回来的时候,你会发现你女儿垒球教练的消息等着你。三个女孩,特雷西,丽贝卡,艾米已经失去了球队帽。你能摆脱竞技产品店,买女孩的帽子。他们的父母会在下一场比赛中报销你。

你知道女孩,你知道他们的父母。但你不知道他们的帽子大小。在你镇的某个地方有三个住宅,每个都有一个您需要的信息。没问题,你只要打电话给父母,得到帽子的大小。您可以拨打手机,然后到达索引 - 电话簿的白页。

您需要达到的第一个住所是Helen Meyer。估计“迈耶”将位于人口中部附近,你跳到白页的中间;只发现你在页面上的标题为“Kline-Koerber”。你进一步向前跳,到达“Niger-Nyeong”页面。一个甚至更小的跳跃让你进入“马尔多纳多 - 尼格尔”页面。意识到您现在在正确的页面,您扫描页面,直到您到达“迈耶,海伦”行并获得电话号码。使用电话号码,您可以到达迈耶居所,并获取您需要的信息。

您再重复一次这个过程,再到另外两个居住地,再获得两个帽子大小。

你刚刚使用了一个索引,并且使用它与SQL Server使用索引的方式大致相同。因为有很大的相似之处,以及白皮书和SQL Server索引之间的一些区别。
实际上,您刚刚使用的索引代表SQL Server支持的两个SQL Server索引类型:集群和非聚簇。白页最好代表非聚簇索引的概念。因此,在这个层次上,我们引入非聚簇索引。后续级别将引入集群索引,并对这两种类型进行更深入的挖掘。

非聚簇索引

白页类似于非聚簇索引,因为它们不是数据本身的组织;而是一种机制或地图来帮助您访问该数据。数据本身就是我们需要联系的实际人员。电话公司不会安排该镇的住宅有意义的顺序,将房屋从一个位置移动到另一个位置,以使同一垒球队中的所有女孩彼此隔壁相隔,房屋不按居民姓氏组织。相反,它给你一本书包含每个住所的一个条目。这些条目由白页的搜索关键字排序;姓氏,名字,中间初始和街道地址。每个条目都包含搜索关键字和使您可以访问住所的数据;电话号码。

像一个条目白皮书,SQL Server非聚簇索引中的每个条目都包含两部分:

搜索键,如姓氏 - 名字 - 中间初始。 。在SQL Server术语中,这是索引键。

书签与电话号码相同,允许SQL Server直接导航到与该索引条目对应的表中的行。

此外,SQL Server非聚簇索引条目具有一些仅内部使用的头信息,并且可能包含一些可选信息。这两个都将在以后的层面上予以涵盖;此时对于非聚簇索引的理解也不重要。

像白页一样,在搜索关键字序列中维护一个SQL Server索引,以便可以在一组小的“跳转”中访问任何特定的条目。给定搜索关键字,SQL Server可以快速获取该密钥的索引条目。与白页不同,SQL Server索引是动态的。也就是说,SQL Server会在每次添加,删除行或修改搜索关键字列值时更新索引。

正如白页中的条目序列与城镇内的住宅地理序列不同;非聚簇索引中的条目序列与表中的行序列不同。索引中的第一个条目可能是表中最后一行,索引中的第二个条目可能是表中第一行。如果事实与索引不同,索引始终是有意义的序列;表的行可以完全没有排序。

创建索引时,SQL Server会在基础表中的每一行的索引中生成并维护一个条目(当覆盖过滤后的索引时,将会遇到此通用规则的一个例外)。您可以在表上创建多个非聚簇索引,但不能包含包含来自多个表的数据的索引。

而最大的区别是:SQL Server不能使用电话。它必须使用索引条目的书签部分中的信息导航到表的相应行。当SQL Server需要数据行中的任何信息,但不在相应的索引条目中时,这将是必需的,例如Tracy Meyer的垒球帽大小。所以,为了更好的比喻,白页的条目包含一组GPS坐标而不是一个电话号码。然后,使用GPS坐标导航到由白页条目表示的住宅。

创造和受益于非聚集索引

我们通过两次查询我们的示例数据库来结束这个级别。 确保您正在使用适用于SQL Server 2005的AdventureWorks版本,可由SQL Server 2008使用。AdventureWorks2008数据库具有不同的表结构,下面的查询将失败。 我们每次都会运行相同的查询; 但在我们在表上创建一个索引之前,第一个执行将会发生,第二个执行将在我们创建一个索引之后。 每次SQL Server会告诉我们在检索所请求的信息方面做了多少工作。 我们将在我们的联系表中找到“Helen Meyer”行(她的行位于表的中间附近)。 最初,表不会在FirstName列或LastName列上有一个索引。 为确保您可以多次运行示例,请确保我们将在第三批中构建的索引不存在,方法是运行以下代码:

IF EXISTS (SELECT * FROM sys.indexes
WHERE OBJECT_ID = OBJECT_ID("Person.Contact")
AND name = "FullName")
DROP INDEX Person.Contact.FullName; 

清单1.1 - 确保索引不存在

我们的任务将需要四个SQL命令批处理。

第一个命令批次:

SET STATISTICS io ON
SET STATISTICS time ON
GO

清单1.2 - 开启统计

上述批次通知SQL Server,我们希望我们的查询作为输出的一部分返回性能信息。

第二个命令批次:

SELECT *
    FROM Person.Contact
    WHERE FirstName = "Helen"
        AND LastName = "Meyer";
GO

清单1.3 - 检索一些数据

第二批检索“Helen Meyer”行:

584 Helen Meyer helen2@adventure-works.com   0-519-555-0112

再加上以下性能信息:

Table "Contact". Scan count 1, logical reads 569.
SQL Server Execution Times:   CPU time = 3 ms.

该输出通知我们,我们的请求执行了569个逻辑IO,并且需要大约3毫秒的处理器时间来执行此操作。 您的处理器时间值可能不同。

第三个命令批次:

CREATE NONCLUSTERED INDEX FullName
            ON Person.Contact
    ( LastName, FirstName );
GO

清单1.4 - 创建非聚集索引

此批次在联系人表的名字和姓氏列上创建非聚簇复合索引。 复合索引是具有多个列的索引,确定索引行序列。

第四个命令批次:

SELECT *
    FROM Person.Contact
    WHERE FirstName = "Helen"
        AND LastName = "Meyer";
GO

清单1.3(再次)

最后一批是重新执行我们原始的SELECT语句。 我们得到与以前一样返回的同一行; 但是这次性能统计数据是不同的

Table "Contact". Scan count 1, logical reads 4.
SQL Server Execution Times:   CPU time = 0 ms.

该输出通知我们,我们的请求只需要4个逻辑IO; 并且需要非常少量的处理器时间来检索“Helen Meyer”行。

结论

创建精心挑选的索引可以大大提高数据库性能。 在下一级,我们将开始研究索引的物理结构。 我们将研究为什么这个非聚集索引对这个查询是如此有益的,为什么可能并不总是这样。 未来的水平将涵盖其他类型的指数,指数的附加利益,与索引相关的成本,监控和维护您的指数以及最佳做法; 所有这些都旨在为您提供必要的知识,为您自己的数据库中的表创建最佳的索引计划。

代码下载

Level 1 - IntroToIndexes_Durant_Code.sql

Level 1 - MillionRowContactTable.sql

Resources:

Level 1 - IntroToIndexes_Durant_Code.sql | Level 1 - MillionRowContactTable.sql


文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/32170.html

相关文章

  • 深入非聚集索引SQL Server索引进阶 Level 2

    摘要:清单创建一个非聚集索引请记住,非聚簇索引按顺序存储索引键,以及用于访问表中实际数据的书签。非聚集索引是一组有序的条目。忽略非聚簇索引并扫描表中 作者David Durant,2017/10/18(首次发布于:2014/11/26) 关于系列 本文属于进阶系列:Stairway to SQL Server Indexes 索引是数据库设计的基础,并告诉开发人员使用数据库关于设计者的意图。...

    array_huang 评论0 收藏0
  • SQL Server 索引内部结构:SQL Server 索引进阶 Level 10

    摘要:索引条目也被称为索引行无论是表行聚簇索引叶级别条目,是指表行非聚簇索引叶级别还是指向较低级别非叶级别的页面。索引中的每个页面无论其级别都包含索引行或条目。结论索引的结构使能够快速访问特定索引键值的任何条目。 作者David Durant,2012年1月20日 关于系列 本文属于Stairway系列:SQL Server索引进阶的一部分 索引是数据库设计的基础,并告诉开发人员使用数据库关...

    fnngj 评论0 收藏0
  • 聚集索引SQL Server 进阶 Level 3

    摘要:而且,有两个外键,足以说明一些关于聚簇索引的设计决策。但现在,把聚簇索引看作是一个有序表。表检索单个产品的所有行前两个查询大大受益于聚簇索引的存在第三个是大致相等的。一般来说,检索效益大于维护损害使聚簇索引更适合堆。 作者:David Durant,2013/01/25(首次发布于:2011/06/22) 关于系列 本文是属于Stairway系列:Stairway to SQL Ser...

    SimpleTriangle 评论0 收藏0
  • 阅读查询计划:SQL Server 索引进阶 Level 9

    摘要:图形查询计划查询计划是执行查询的一组指令。哈希如果传入数据的顺序不合适,可能会使用散列操作对数据进行分组。另一方面会导致大量的群体,每个群体都需要自己的记忆空间可能消耗太多内存,哈希成为解决查询的不良技术。有关查询计划散列的 David Durant,2011/10/05 关于系列 本文是属于Stairway系列:Stairway to SQL Server Indexes 索引是数据...

    ysl_unh 评论0 收藏0
  • 包含列的索引SQL Server索引进阶 Level 5

    摘要:在这个级别中,我们检查选项以将其他列添加到非聚集索引称为包含列。清单创建包含列的非聚集索引在本例中,和是索引键列,,和是包含的列。结论包含的列使非聚集索引能够覆盖各种查询的索引,从而提高这些查询的性能有时相当戏剧性。 作者David Durant,2011/07/13 关于系列 本文属于Stairway系列:Stairway to SQL Server Indexes 索引是数据库设计...

    boredream 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<