索引访问方法及索引优化

要了解索引访问方法,首先要知道索引的结构。

1.表和索引的结构 

页是sql server存储数据的基本单位,大小为8kb,可以存储表数据、索引数据、执行计划数据、分配位图、可用空间信息。页是sql server可以读写的最小I/O单位。即便是读取一行数据,它也要把整个页加载到缓存并从缓存中读取数据。

区是由8个连续页组成的分配单元。

堆是指不含聚集索引的表,它的数据不按任何顺序进行存储。

联系一个堆中的数据的唯一结构是被称为索引分配映射(IAM)的一个位图页,当扫描对象时,SQl server使用IAM页来遍历该对象的数据。

聚集索引:

它的叶级表中维护所有数据,按照索引键列的顺序存储在索引的叶级。在索引页级别的上层,索引还维护着其他级别,每个级别都概况了它下面的级别,非叶级索引上的每一行指向它下一级别的整个页。

堆上的非聚集索引:

与聚集索引的唯一区别是非聚集索引的叶级页只包含索引键列和指向特定数据行的行定位符,称为RID。当通过索引查找到特定的数据行后,Sqlserver必须在seek操作之后执行RID lookup操作,该操作用于读取包含数据行的页。

聚集表上的非聚集索引:

指向特定数据行的行定位符是聚集键的值,不是RID。

2.索引访问方法 

表扫描/无序聚集索引扫描

当表中没有索引时,连续的扫描表中的所有数据页。SQl server将根据该表的IAM页指示磁盘取数臂按物理顺序扫描属于该表的区。

当表包含聚集索引时,所采取的方法将是无序聚集索引扫描。

示例sql:select orderid,custid,empid,shipperid,orderdate,filler from dbo.Orders

索引:CREATE CLUSTERED INDEX idx_cl_od ON dbo.Orders(orderdate);

表Orders结构: orderid,custid,empid,shipperid,orderdate,filler

覆盖非聚集索引扫描

Sql server 只访问索引数据就可以找到满足查询所需的全部数据,不需要访问完整的数据行。

示例sql:select orderid from dbo.Orders

索引:ALTER TABLE [dbo].[Orders] ADD  CONSTRAINT [PK_Orders] PRIMARY KEY NONCLUSTERED

(

[orderid] ASC

)

有序聚集索引扫描

按照链接列表对聚集索引叶级执行的完整扫描 操作。

示例sql:select orderid,custid,empid,shipperid,orderdate,filler from dbo.Orders order by orderdate

索引:

CREATE CLUSTERED INDEX idx_cl_od ON dbo.Orders(orderdate);

不同于无序索引扫描,有序扫描的性能取决于索引的碎片级别。

有序覆盖非聚集索引扫描

与有序聚集索引扫描类似,但是覆盖非聚集索引扫描时,因为它涉及更少的页,它的成本肯定比聚集索引索引扫描要低。

示例sql:select orderid, orderdate from dbo.Orders order by orderid

非聚集索引索引查找+有序局部扫描+lookups

通常用于小范围查询,且用到的非聚集索引没有覆盖该查询。

示例sql:select orderid,custid,empid,shipperid,orderdate,filler from dbo.Orders where orderid between 101 and 200

无序非聚集索引扫描 + lookups

通常符合以下情况时,优化器会选择此种访问方法:

  1. 该查询的选择性足够高
  2. 最适合某查询的索引并不覆盖该查询
  3. 索引没有按顺序维护被查找键

示例sql:select orderid,custid,empid,shipperid,orderdate,filler from dbo.Orders where custid = ‘’

聚集索引查找+有序局部扫描

对于按聚集索引的第一个键列进行筛选的范围查询,优化器通常使用这种方法。

示例sql:select orderid,custid,empid,shipperid,orderdate,filler from dbo.Orders where orderdate = ‘20060212’

这种方法的好处是不涉及lookups.

覆盖非聚集索引查找+有序局部扫描

访问方法与上一个类似,唯一的区别是非聚集索引。相对于上一个访问方法,这个方法的好处在于非聚集索引的的叶级页比聚集索引的叶级页能够容纳更多的行。

示例sql: select shipperid,orderdate, custid from dbo.Orders

Where shipperid=‘C‘ and orderdate >=‘20060101‘ and orderdate <‘20070101‘

CREATE NONCLUSTERED INDEX idx_nc_sid_od_cid

ON dbo.Orders(shipperid, orderdate, custid);

3.索引优化等级

需要优化的sql:select orderid,custid,empid,shipperid,orderdate,filler from dbo.Orders where orderid > 999001

1.这个表没有任何索引:该计划将使用表扫描

2.接下来优化,创建一个非聚集覆盖索引,且不把筛选列(orderid)作为第一个筛选列:

CREATE INDEX idx_nc_od_i_oid_cid_eid_sid

ON performance.dbo.Orders(orderdate)

include(orderid,custid,empid,shipperid);

优化器将采用覆盖非聚集索引扫描

3.下一步优化:创建一个不覆盖该查询的非聚集索引

CREATE NONCLUSTERED INDEX idx_nc_od_i_oid

ON dbo.Orders(orderdate)

INCLUDE(orderid);

优化器将采用非聚集索引扫描+lookup,这个查询依赖于选择性。选择性越高,性能越高。

4.继续优化:在orderid上创建非聚集非覆盖索引,

CREATE UNIQUE NONCLUSTERED INDEX idx_unc_oid

ON dbo.Orders(orderid);

优化器将采用非聚集索引查找+lookup

5.继续优化:在orderid上创建聚集索引

CREATE UNIQUE CLUSTERED INDEX idx_cl_oid ON dbo.Orders(orderid);

这个计划主要不涉及lookup,

6.继续优化:

最佳优化应该是把orderid作为键列,并把其他列定义为包含性非键列的非聚集覆盖索引。

CREATE UNIQUE NONCLUSTERED INDEX idx_unc_oid_i_od_cid_eid_sid

ON dbo.Orders(orderid)

INCLUDE(orderdate, custid, empid, shipperid);

这个计划的逻辑与上一个类似,只是非聚集覆盖索引有序局部扫描读取的页更少。

时间: 2024-10-05 05:20:47

索引访问方法及索引优化的相关文章

MySQL索引使用方法和性能优化

关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车.对于没有索引的表,单表查询可能几十万数据就是瓶颈,而通常大型网站单日就可能会产生几十万甚至几百万的数据,没有索引查询会变的非常缓慢.还是以WordPress来说,其多个数据表都会对经常被查询的字段添加索引,比如wp_comments表中针对5个字段设计了BTREE索引. 一个简单的对比测试 以我去年测试的数据作为一个简单示例,20多条数据源随机生成200万条

图解PG12--表及索引访问方法架构

原文地址:https://blog.51cto.com/yanzongshuai/2465980

访问索引的方法

首先要说明一点,以下提到是oracle数据库最常用的B树索引,oracle数据其他类型的索引暂不考虑,B树索引就好像一棵倒长的树,它包含两种类型的数据块,一种是索引分支块,另一种是索引叶子块. 索引分支块包含指向响应索引分支块/叶子块的指针和索引键值列(这里的指针是指相关分支块/叶子块的块地址RDBA,每个索引分支块都有两种类型的指针,一种是lmc,另一种是索引分支块的索引行记录的指针.lmc是left Most Child的缩写,每个索引分支块都只有一个lmc,这个Imc指向的分支块/叶子块中

MySQL优化GROUP BY-松散索引扫描与紧凑索引扫描

满足GROUP BY子句的最一般的方法是扫描整个表并创建一个新的临时表,表中每个组的所有行应为连续的,然后使用该临时表来找到组并应用累积函数(如果有).在某些情况中,MySQL能够做得更好,即通过索引访问而不用创建临时表. 为GROUP BY使用索引的最重要的前提条件是所有GROUP BY列引用同一索引的属性,并且索引按顺序保存其关键字.是否用索引访问来代替临时表的使用还取决于在查询中使用了哪部分索引.为该部分指定的条件,以及选择的累积函数. 由于GROUP BY 实际上也同样会进行排序操作,而

MongoDB 索引的使用, 管理 和优化

MongoDB 索引的使用, 管理 和优化 2014-03-25 17:12 6479人阅读 评论(0) 收藏 举报  分类: MongoDB(9)  [使用explain和hint] 前面讲高级查询选项时,提到过"$explain" 和 ”$hint“可以作为包装查询的选项关键字使用,其实这两个本身就可以作为操作游标的函数调用!游标调用explain函数会返回一个文档,用于描述当前查询的一些细节信息.这也不同于我们前面介绍的游标函数,前面提到的游标处理函数都是返回游标,可组成方法链调

SqlServer 创建聚集索引与非聚集索引处理千万条数据的优化,以及之间的区别

在以下的文章中,我将以"办公自动化"系统为例,探讨如何在有着1000万条数据的MS SQL SERVER数据库中实现快速的数据提取和数据分页.以下代码说明了我们实例中数据库的"红头文件"一表的部分数据结构: CREATE TABLE [dbo].[TGongwen] ( --TGongwen是红头文件表名 [Gid] [int] IDENTITY (1, 1) NOT NULL , --本表的id号,也是主键 [title] [varchar] (80) COLLA

重新学习MySQL数据库5:根据MySQL索引原理进行分析与优化

重新学习MySQL数据库5:根据MySQL索引原理进行分析与优化 一:Mysql原理与慢查询 MySQL凭借着出色的性能.低廉的成本.丰富的资源,已经成为绝大多数互联网公司的首选关系型数据库.虽然性能出色,但所谓"好马配好鞍",如何能够更好的使用它,已经成为开发工程师的必修课,我们经常会从职位描述上看到诸如"精通MySQL"."SQL语句优化"."了解数据库原理"等要求.我们知道一般的应用系统,读写比例在10:1左右,而且插入

ORACLE Index Lookup索引访问路径总结

在ORACLE中,索引访问/查找(Index Lookup)路径有五种方式,分别为INDEX UNIQUE SCAN.INDEX RANGE SCAN.INDEX FULL SCAN.INDEX FAST FULL SCAN .INDEX SKIP SCAN.下面通过一些案例介绍.总结一下这五种索引访问路径.本文是总结这方面的知识点,所以文中一些地方参考.引用了参考资料中的部分内容.详细.具体资料可以参考官方资料Index Scans 索引唯一扫描(INDEX UNIQUE SCAN)   索引

索引、视图、SQL优化以及数据库存储过程

一.索引 索引是查询优化最有效和最常用的技术 索引是一个单独的.物理的数据库结构,它是指向表中某一列或若干列上的指针列表. mysql中,一个表的物理存储由两部分组成,一部分用于存放表的数据,另一部分存放索引,当进行数据搜索时,mysql会首先搜索索引,从中找到所需数据的起始位置的指针,再直接通过指针查找目标数据. 1.创建索引: CREATE INDEX 索引名 on 表名(要添加索引的列名) 可以给一个表中的多个列添加索引 通过在查询sql语句前加一句Explain可以分析索引效率, 有这样