索引深入浅出(10/10):创建索引时,键列位置的重要性

在过去的文章里,我们已经讨论了各种不同索引。这个文章里,我们会讨论下键列的顺序(索引列的顺序)。索引键列的顺序基于数据的访问模式还有你想如何组织数据。

对于索引键列的顺序,常规指导方针就是把查询用到最多的列放在第一列。这并不是说,所有你索引里的唯一ID列就应该是第一列。优化器是基于索引上的可用统计信息来选择索引的。统计信息会给你键列的使用密度信息,即索引的唯一性,直方图(histogram )用来存储那一列值分布情况信息。

让我们用customer表做例子,它保存来自各个国家的客户信息。

 1 CREATE TABLE customer (
 2    Customer_id     INT IDENTITY(1,1) NOT NULL,
 3    CountryCode     CHAR(3) NOT NULL,
 4    FirstName       VARCHAR(100) NOT NULL,
 5    LastName        VARCHAR(100) NOT NULL,
 6    MobilePhone     VARCHAR(20),
 7    Email           VARCHAR(100)
 8 )
 9 GO
10 CREATE UNIQUE CLUSTERED INDEX Ix_Customerid_Countrycode ON customer(Customer_id,Countrycode)

聚集索引的创建是基于常规指导方针,我们把经常用到的列放在了左边。如果我基于Customer_id列来获取记录,这个聚集索引非常合适。如果我是基于Countrycode列,优化器就要进行聚集索引扫描了。

1 SET STATISTICS IO ON
2 go
3 SELECT * FROM customer WHERE Countrycode=‘VNH‘ AND customer_id=1216468

我们来找下countrycode 是VHN的所有客户。这个表有近620000条记录,3066条记录的countrycode是VHN。

1 SELECT * FROM customer WHERE Countrycode=‘VNH‘ 

从执行计划可以看到,优化器进行了聚集索引扫描,共扫描了6825页。我们可以修改聚集键的顺序来优化。

1 DROP INDEX customer.Ix_CustomerId_CountryCode
2 GO
3 CREATE UNIQUE CLUSTERED INDEX Ix_CountryCode_CustomerId ON customer(Countrycode,Customer_id)
4
5 SET STATISTICS IO ON
6 go
7 SELECT * FROM customer WHERE Countrycode=‘VNH‘ AND customer_id=1216468

我们来找下countrycode 是VHN的所有客户。

1 SELECT * FROM customer WHERE Countrycode=‘VNH‘ 

从执行计划可以清楚看到,优化器在这2个情况都使用了索引查找(index seek),但在找countrycode 是VHN的所有客户时,IO操作明显上升。

当保持customer_id为第一列时,数据会按customer_id列的顺序保存,你会有很多页(几乎所有页),里面的数据属于多个countrycode。这个会引起阻塞/死锁。如果我们定义countrycode为第一列,只有少量页,里面的数据与多个countrycode重叠,这样会减少阻塞问题。关键点是:把countrycode定义为索引的第一列会引起更高级别的索引碎片,这可以用定义合适的填充因素值(fill factor value)来控制。

简而言之,键列的常规指导方针是个很好的起点,但是你也要考虑在你程序里的数据访问模式。希望这个可以帮助你解决你遇到的一些问题。

时间: 2024-08-02 19:58:50

索引深入浅出(10/10):创建索引时,键列位置的重要性的相关文章

索引深入浅出:非聚集索引的B树结构在聚集表

一个表只能有一个聚集索引,数据行以此聚集索引的顺序进行存储,一个表却能有多个非聚集索引.我们已经讨论了聚集索引的结构,这篇我们会看下非聚集索引结构. 非聚集索引的逻辑呈现 简单来说,非聚集索引是表的子集.当我们定义了一个非聚集索引时,SQL Server把整套非聚集索引键存在不同的页里.我们来看下一个包含BusinessEntityID(PK),PersonType,FirstName,LastName这4列的表,这个表上有一个非聚集索引定义.主体表按BusinessEntityID列(聚集索引

索引深入浅出:非聚集索引的B树结构在堆表

在“索引深入浅出:非聚集索引的B树结构在聚集表”里,我们讨论了在聚集表上的非聚集索引,这篇文章我们讨论下在堆表上的非聚集索引. 非聚集索引可以在聚集表或堆表上创建.当我们在聚集表上创建非聚集索引时,聚集索引键担当为行指针.在堆表里,文件号,页号和槽号(file id , page number and slot number)的组合在非聚集索引里担当为行指针. 我们来看下手头的一个例子.我们创建salesorderdetail表的副本,并在上面的productid和salesorderid 列创

索引深入浅出(9/10):过滤索引

过滤索引(Filtered index )是在SQL Server 2008里新引入的功能.到目前我们谈到的索引都是在建立在整张表上的.换句话说,索引和表有一样的记录树.使用过滤索引,我们可以创建表子集的索引.这个可以通过创建索引的时候加上where子语完成.这个可以帮助在存储上减小索引的大小同样索引的深度.在索引创建语句的where条件决定了索引里是否包含该记录. 这在大表上是一个巨大的性能提升,如果有大量的查询只查表的部分数据.常规索引都是建立在整个表上的,而忽略了大多数查询只查表的一部分数

一步一步跟我学习lucene(6)---lucene索引优化之多线程创建索引

这两天工作有点忙,博客更新不及时,请大家见谅: 前面了解到lucene在索引创建的时候一个IndexWriter获取到一个读写锁,这样势在lucene创建大数据量的索引的时候,执行效率低下的问题: 查看前面文档一步一步跟我学习lucene(5)---lucene的索引构建原理可以看出,lucene索引的建立,跟以下几点关联很大: 磁盘空间大小,这个直接影响索引的建立,甚至会造成索引写入提示完成,但是没有同步的问题: 索引合并策略的选择,这个类似于sql里边的批量操作,批量操作的数量过多直接影响执

物化视图,索引视图,函数索引,创建索引时使用DESC

老板交给的一个任务,搜了一下资料,觉得还是总结一下比较好.假如以后用到了呢?围绕两个主题:一是视图上能够建索引,二是在创建索引时是否可以使用DESC关键字. 一.能否在视图上创建索引 因为普通的视图并没有存储实际的信息,它所操作的数据来自于基本表,所以在普通视图上不可以创建索引. 在oracle中执行如下的语句,会报"视图不适用于此处"的错误 create view test_car as select license from cars; create index index_vew

mysql创建索引以及对索引的理解

创建索引是指在某个表的一列或多列上建立一个索引,以便提高对表的访问速度.创建索引有3种方式,这3种方式分别是创建表的时候创建索引.在已经存在的表上创建索引和使用ALTER TABLE语句来创建索引.本节将详细讲解这3种创建索引的方法. 7.2.1  创建表的时候创建索引(1) 创建表时可以直接创建索引,这种方式最简单.方便.其基本形式如下: CREATE TABLE  表名( 属性名 数据类型[完整性约束条件], 属性名 数据类型[完整性约束条件], ...... 属性名 数据类型  [ UNI

数据库创建索引的利弊

索引就像是书的目录,是与表或视图关联的磁盘上结构,可以加快从表或视图中检索行的速度.索引中包含由表或视图中的一列或多列生成的键.这些键存储在一个结构(BTree)中,使SQL可以快速有效地查找与键值关联的行. 2. 为什么要建立索引,即索引的优点: ①  建立索引的列可以保证行的唯一性,生成唯一的rowId ②  建立索引可以有效缩短数据的检索时间 ③  建立索引可以加快表与表之间的连接 ④  为用来排序或者是分组的字段添加索引可以加快分组和排序顺序 3. 索引的缺点: ①  创建索引和维护索引

Lucene.net 从创建索引到搜索的代码范例

关于Lucene.Net的介绍网上已经很多了在这里就不多介绍Lucene.Net主要分为建立索引,维护索引和搜索索引Field.Store的作用是通过全文检查就能返回对应的内容,而不必再通过id去DB中加载.Field.Store.YES:存储字段值(未分词前的字段值)Field.Store.NO:不存储,存储与索引没有关系Field.Store.COMPRESS:压缩存储,用于长文本或二进制,但性能受损Field.Index.ANALYZED:分词建索引 Field.Index.ANALYZE

(转)SQL Server创建索引

什么是索引拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般为4K .为了加快查找的速度,汉语字(词)典一般都有按拼音.笔画.偏旁部首等排序的目录(索引),我们可以选择按拼音或笔画查找方式,快速查找到需要的字(词).同理,SQL Server允许用户在表中创建索引,指定按某列预先排序,从而大大提高查询速度.? SQL Server中的数据也是按页( 4KB )存放? 索引:是SQL Server编排数据的内部方法.它为