SQL Server索引 - 非聚集索引 <第七篇>

一、非聚集索引维护

  非聚集索引的行定位器值保持相同的聚集索引值,即使该聚集索引列物理上重新定位后,也是如此。

  为了优化这个维护开销,SQL Server添加一个指向旧数据页的指针,以在页面分割之后指向新的数据页面,而不是更新所有相关非聚集索引的行定位器。这样,虽然降低了非聚集索引的维护开销,但是增加了从非聚集索引行到数据行的导航开销,因为添加了一个旧数据页面和信数据页面之间的连接。因此,将聚集索引作为行定位器降低了非聚集索引相关的开销。

二、定义书签查找

  当一个查询请求不是优化器选择的非聚集索引一部分的列时,需要一个查找。这对一个聚集索引来说是一个关键字查找,堆堆表来说是一个RID查找。这些查找的统称来自于旧的定义名 - 书签查找。这种查找根据非聚集索引的行定位器值,从表中读取对应的数据行,除了索引页面上的逻辑读操作意外,还需要一个数据页面上的逻辑读。但是,如果查询需要的列在索引中,那么就不需要访问数据页面。这被称为覆盖索引。

  这些书签查找是大结果集最好使用聚集索引的原因。聚集索引不需要书签查找,因为叶子页面就是数据页面。

三、非聚集索引的建议

  因为表只能有一个聚集索引,所以可以使用多个非聚集索引的灵活性来帮助改进性能。下面将说明非聚集索引使用的决定因素。

  1、何时使用非聚集索引

  非聚集索引在需要从一个大表上读取少量的行的时候最有用,随着需要检索的行数量的增加,书签查找的开销成比例增加。为了从表中检索少量的行,索引列应该有很高的选择性。

  适合使用非聚集索引的情况:

  • 列具有高选择性;
  • 根据列获取少量数据;
  • 窄列;
  • 列经常被分组排序;

  下面给出不适合建立聚集索引,但也能够使用聚集索引的情况

  •   频繁更新的列;
  •   宽类型列;

  聚集索引频繁更新是非常消耗资源的,因为会影响表的顺序,同时也影响到其他索引,在频繁更新的列上的非聚集索引的开销不像聚集索引那么大。在非聚集索引上的更新操作被限定在基本表和非聚集索引上,它不影响表上的其他非聚集索引。

  宽类型列也类似,非聚集索引列上使用宽类型,虽影响比如聚集索引那么大,但是也要小心使用。

  2、何时不使用聚集索引

  非聚集索引不适合于大量行的查询。这样的查询使用聚集索引更好,聚集索引不需要大量的书签查找,而非聚集索除了在索引列上检索的逻辑读外,书签查找也需要消耗太多资源。SQL Server查询优化器在检索大结果集时会考虑这一开销,并相应地放弃该非聚集索引。

不适合建非聚集索引的情况:
获取大量数据;
低选择性;

SQL Server索引 - 非聚集索引 <第七篇>,布布扣,bubuko.com

时间: 2024-10-08 11:13:45

SQL Server索引 - 非聚集索引 <第七篇>的相关文章

程序员眼中的 SQL Server-非聚集索引能给我们带来什么?

 我不会说一些数据库概念,所以只能用做一些实践来理解概念的意义,以下应用场景中的用例是虚拟出来的,只是作为个人研究使用. 程序员应该有刨根问底的怪癖,虽然这是个数据库问题. 应用场景 有一个 Product 表,字段如下: 数据添加脚本: begin tran declare @index int set @index=0 while(@index<1000000) begin insert into [dbo].[Product]([Name],Remarks,ProviderID,[Ti

Mysql 索引实现原理. 聚集索引, 非聚集索引

Mysql索引实现: B-tree,B是balance,一般用于数据库的索引.使用B-tree结构可以显著减少定位记录时所经历的中间过程,从而加快存取速度.而B+tree是B-tree的一个变种,MySQL就普遍使用B+tree实现其索引结构. 一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上.这样的话,索引查找过程中就要产生磁盘I/O消耗,相对于内存存取,I/O存取的消耗要高几个数量级,所以评价一个数据结构作为索引的优劣最重要的指标就是在查找过程中磁盘

07.索引-非聚集索引(3)-Key Lookup &amp;RID Lookup

如果存在聚集索引并且查找的列不在 非聚集索引的键列中 而在没有聚集索引的表中 使用RID Lookup 书签查找可能因为开销过大导致一些查询直接进行表扫描 聚集索引所有数据都在索引中(数据页也是索引的一部分),因此可以直接通过聚集索引找到所有的列 定位到索引,也就意味着数据找到了 但是非聚集索引定位到索引后,需要在根据索引记录的RID或者Key 查找数据行,势必会导致一次数据页的I/O 数据行过多,形成的数据页IO也会非常大 当数据过大,IO反而可能超过直接进行页扫描的开销,因此系统会选择进行页

索引 - 非聚集索引设计指南-转载

非聚集索引包含索引键值和指向表数据存储位置的行定位器. 有关非聚集索引体系结构的详细信息, 请参阅 非聚集索引结构. 可以对表或索引视图创建多个非聚集索引. 通常, 设计非聚集索引是为改善经常使用的没有建立聚集索引的查询的性能. 与使用书中索引的方式相似, 查询优化器在搜索数据值时, 先搜索非聚集索引以找到数据值在表中的位置, 然后直接从该位置检索数据. 这使非聚集索引成为完全匹配查询的最佳选择, 因为索引包含说明查询所搜索的数据值在表中的精确位置的项. 例如, 为了从 Person.Perso

05.索引-非聚集索引(1)-聚集表

建立非聚集索引 CREATE NONCLUSTERED INDEX NCIX_Employee001_Department_Organization ON Employee001(Department,Organization); ALTER INDEX NCIX_Employee001_Department_Organization ON Employee001 REORGANIZE 索引情况 SELECT database_id, index_id, index_type_desc, ind

08.索引-非聚集索引(4)-联合索引、覆盖索引

避免书签查找 可以将查询需要的列加入非聚集索引中 联合索引会导致所有的非聚集索引页中都会冗余一份列的数据,尤其是当这些列不作为条件,只作为返回值时候,是一种浪费 因此可以 选择将查询结果需要的列加入覆盖索引 这时候 覆盖的列 只会存在于叶节点中,定位到索引后,直接从页节点返回数据,避免再根据RID 或者Key 读取数据页,可以减少一次IO

06.索引-非聚集索引(2)-堆表

删除聚集索引 DROP INDEX CIX_Employee001_Id ON Employee001 索引情况 SELECT database_id, index_id, index_type_desc, index_depth, index_level, page_count FROM sys.dm_db_index_physical_stats(DB_ID('IndexDB'),OBJECT_ID('Employee001'),null,null,null) TRUNCATE TABLE

35. SQL -- 聚集索引和非聚集索引(1)

索引概述: 用户对数据库最频繁的操作是进行数据查询.一般情况下,数据库在进行查询操作时需要对整个表进行数据搜索.当表中的数据很多时,搜索数据就需要很长的时间,这就造成了服务器的资源浪费.为了提高检索数据的能力,数据库引入了索引机制.数据库索引好比是一本书前面的目录,能加快数据库的查询速度. 例如这样一个查询: select * from table1 where id=44. 如果没有索引,必须遍历整个表,直到ID 等于44 的这一行被找到为止:有了索引之后(必须是在ID 这一列上建立的索引),

读书笔记:一个非聚集索引查询引起的“表扫描” + “阻塞”问题

以下是使用AdventureWorks2008R2数据库测试一个因全表扫描而引起的阻塞问题. 步骤: 一.建表 CREATE TABLE Employee_Demo_Heap( [BusinessEntityID] [int] NOT NULL, [NationalIDNumber] [nvarchar](15) NOT NULL, [LoginID] [nvarchar](256) NOT NULL, [OrganizationNode] [hierarchyid] NULL, [Organi