`

索引举例介绍

    博客分类:
  • SQL
阅读更多
Description:
 查询优化器在从表中查询数据时,需要选择一个合适的访问模式,在决定使用哪一种索引,使用扫描还是查找,使用书签查询时,查询优化器要考虑许多因素,这些因素包括:
  • 索引执行时,查找或扫描所需的I/O数
  • 评估查询中的索引键是否是最佳
  • 谓词的选择性(也就是说,相对于表中总记录数满足谓词的百分比)
  • 索引是否覆盖所有列?

下面通过一个例子来介绍:

create table T (a int, b int, c int, d int, x char(200))

create unique clustered index Ta on T(a)

create index Tb on T(b)

create index Tcd on T(c, d)

create index Tdc on T(d, c)

插入一些数据:

set nocount on

declare @i int

set @i = 0

while @i < 100000

begin

insert T values (@i, @i, @i, @i, @i)

set @i = @i + 1

end

无Where条件

Select a,b FROM T,

该 查询不包含Where条件语句,而使用扫描,可是这里有两种索引可用:聚集索引(Ta)和非聚集索引(Tb),这两个索引均覆盖a和b两列,另外,聚集索 引也覆盖c和x列.由于x列是字符型,长度为200个字符,聚集索引的每一行总宽度超过了200个字节,对于每一个8KB的页面,存储的行数也不超过40 行.而索引需要2500个页来存储所有10万行数据,与之相反的是,非聚集索引中每一行的总宽仅有8个字节,加一些头部信息,每一页可以存储上百行数据, 索引则需要不到250页来存储所有的10万行数据.通过扫描非聚集索引,当执行查询时则需要较少的I/O操作.因而使用的最佳计划是:

|--Index Scan(OBJECT:([T].[Tb]))

我们也可以使用sys.dm_db_index_physical_stats视图来比较聚集索引与非聚集索引两者所使用的页数

select index_id, page_count

from sys.dm_db_index_physical_stats

(DB_ID('northwind'), OBJECT_ID('T'), NULL, NULL, NULL)

执行上述查询后,结果如下:

索引ID号 页数
1 2858
2 174
3 223
4 223

从输出结果可以看出,非聚集索引存储行所使用的页数明显小于聚集索引使用的页数.

当然我们也可以使用stats I/O和索引hints来比较聚集索引与非聚集索引的I/O数.

set statistics io on

select a, b from T with (index(Ta))

表'T'。扫描计数1,逻辑读取2872 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。

select a, b from T with (index(Tb))

表'T'。扫描计数1,逻辑读取176 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。

从stats I/O数可以看出,非聚集索引在获取数据时,读取较少的数据页.

索引的选择性

select a from T

where c > 150 and c < 160 and d > 100 and d < 200

此查询有两个不同的谓词用于索引查找,可以使用位于c列上的非聚集索引Tcd,也可以使用位于d列上的非聚集索引Tdc.

查询优化器通过查看两个谓词的选择性来确定使用哪一个索引,在c列上的谓词选择的行仅有9行,而在d列上则有99行,显然使用索引Tcd来评估位于d列上的residual谓词比使用Tdc索引的I/O开销要小得多.

以下是该查询的计划:

|--Index Seek(OBJECT:([T].[Tcd]), SEEK:([T].[c] > (150) AND [T].[c] < (160)),

Where:([T].[d]>(100) AND [T].[d]<(200)) orDERED FORWARD)

索引查找与索引扫描示例

select a from T where a between 1001 and 9000

select a from T where a between 101 and 90000

其执I/O信息如下:

表'T'。扫描计数1,逻辑读取234 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。

表'T'。扫描计数1,逻辑读取176 次,物理读取0 次,预读0 次,lob 逻辑读取0 次,lob 物理读取0 次,lob 预读0 次。

如您所预料的,对于第一个查询来说,查询优化器在a列上选择使用聚集索引来获取数据,以下是其的查询计划:

|--Clustered Index Seek(OBJECT:([T].[Ta]),

SEEK:([T].[a] >= CONVERT_IMPLICIT(int,[@1],0) AND [T].[a] <= CONVERT_IMPLICIT(int,[@2],0)) orDERED FORWARD)

注意:该计划中的两个参数是由自动参数化功能所生成的,当执行该计划时,@1参数为1001,@2参数为9000.

对于第二个查询来说,查询优化器却选择了非聚集索引来扫描数据,以下其查询计划:

|--Index Scan(OBJECT:([T].[Tb]), Where:([T].[a]>=(101) AND [T].[a]<=(90000)))

为 什么是这样呢?注意第一个查询选择的记录数有8千行(相对于10万行数据而言),对于聚集索引来说,选择度为表的8%,约230个数据页,而第二查询选择 的记录数有89000行,选择度为表的约90%,若使用聚集索引来读取89000行数据时,则需要读2500个数据页.通过比较,非聚集索引仅需要读取 174个页面,查询优化器选择此计划,大大减少了I/O操作.

带书签查询的查询与扫描示例

select x from T where b between 101 and 200

select x from T where b between 1001 and 2000

对 于上述的两个查询而言,可以通过聚集索引直接扫描然后在列b上应用谓词,或者使用非聚集索引Tb在列b上执行索引查找,然后在聚集索引上执行书签查询来读 取满足x列值的行.(注意:书签查询采用的I/O开销比较大的方式是随机读.)对于查找的选择度高的书签查询,则是值得的.

以下是第一个包含书签查询的查询计划(仅需要读取100行):

|--Nested Loops(Inner Join, OUTER REFERENCES:([T].[a], [Expr1005]) ...)

|--Index Seek(OBJECT:([T].[Tb]), SEEK:([T].[b] >= (101) AND [T].[b] <= (200)) ...)

|--Clustered Index Seek(OBJECT:([T].[Ta]), SEEK:([T].[a]=[T].[a]) LOOKUP ...)

  而第二个查询则读取1000行,对于表而言,仅有1%.查询优化器由此推出,执行1000次的随机读要比执行2800次的顺序读的开销要大得多,第二个查询的计划如下:

|--Clustered Index Scan(OBJECT:([T].[Ta]), Where:([T].[b]>=(1001) AND [T].[b]<=(2000)))

源文出处:http://www.haixiait.com/article.asp?id=162

分享到:
评论

相关推荐

    SQLserver索引失效举例.txt

    SQLserver索引失效举例.txt

    oracle索引使用样例

    ### Oracle索引使用样例详解 #### 一、索引并行创建 在Oracle数据库中,并行创建索引可以显著提高创建索引的速度,尤其是在处理大量数据时。下面的SQL语句展示了如何并行创建一个索引: ```sql CREATE INDEX IDX_GD...

    DB2索引及其优化(设计,优化,问题分析,解答,举例)

    DB2索引及其优化 DB2索引设计及其优化是...在本文中,我们讨论了DB2索引的概念、创建索引、建立索引注意事项、索引分类和索引优化等方面的知识点,并提供了一些有用的提示和建议,以帮助读者更好地理解和应用DB2索引。

    LaTeX论文写作教程-建立索引及文献引用

    LaTeX论文写作教程-建立索引及文献引用 LaTeX是一种基于TeX的排版系统,用于创建高质量的科技文档,如学术论文、书籍、报告等。与传统的字处理软件(如Word)相比,LaTeX具有以下优势: 专业排版:LaTeX提供了丰富...

    MYSQL创建索引全过程

    代码复制粘贴 改下里面的参数 就可以用 而且参数 也有说明 简单易懂

    C语言实现的词索引表程序IndexBook——严蔚敏数据结构词索引表实现

    C语言实现的词索引表程序:IndexBook。C语言实现按照索引插入并查找元素。严蔚敏建立词索引表:严蔚敏数据结构C语言实现,串操作应用举例中的词索引表例子,由于作者没给出完整源码,自己写了一个比较完整的。

    数据库索引

    #### 举例说明 假设有一个名为`T`的表,包含7条记录,表结构存储在`t.frm`文件中,数据存储在`t.ibd`文件中。表的结构和数据如下: - **聚集索引结构**:查询速度最快,只需两次I/O操作。 - **非聚集索引结构(a...

    mysql多条件索引

    举例来说,如果我们有一个名为`people`的表,包含`lname`、`fname`和`age`三列,若要查询姓`Liu`、名`Zhiqun`且年龄为26的用户ID,创建一个`(lname, fname, age)`的多列索引会非常有效。如果只对`lname`创建单列索引...

    bbf算法的详细介绍与应用举例

    ### bbf算法的详细介绍与应用举例 #### 一、引言 在计算机视觉领域,特别是形状索引(Shape Indexing)技术中,一种名为“Best Bin First”(BBF)的搜索算法因其在高维特征空间中的高效表现而受到广泛关注。本文...

    MySql相关面试题举例

    "MySql 相关面试题举例" 本资源摘要信息涵盖了 MySQL 相关的面试题,包括关系型和非关系型数据库的区别、MySQL 语句执行步骤、索引的使用原因、索引的三种常见底层数据结构、索引的常见类型、MyISAM 和 InnoDB 实现...

    数据结构C语言树二叉树详细举例介绍PPT学习教案.pptx

    "数据结构C语言树二叉树详细举例介绍" 本文档为数据结构C语言树二叉树的详细介绍,包括树的类型定义、二叉树的类型定义、二叉树的存储结构、二叉树的遍历、线索二叉树、树和森林的表示方法、树和森林的遍历、哈夫曼...

    ElasticSearch添加索引.docx

    - **字段类型举例**: - `long`:用于整数类型的字段,如`houseId`。 - `text`:用于长文本字段,如`title`、`description`。`index": "true"`表明这个字段需要被分析并建立索引,以便进行全文搜索。 - `integer...

    通过实例认识MySQL中前缀索引的用法

    在MySQL数据库中,索引是优化查询性能的关键工具。前缀索引是一种特殊的索引类型,它允许我们只对字符串的起始部分创建索引,而不是整个字符串。这在处理大字符串时尤其有用,因为完全索引可能会占用大量存储空间,...

    86以MySQL单表查询来举例,看看执行计划包含哪些内容(1)?.pdf

    举例来说,使用一个包含唯一索引的列来查询一个特定的值,如`SELECT * FROM table WHERE id = x`,就会被识别为const类型。因为id作为唯一索引,查询的性能极高。 2. ref:ref是另一种执行计划类型,指的是使用普通...

    MySQL优化介绍和举例

    2. 设计合理的索引:索引可以显著提升查询速度。主键应具有唯一性且不易变动,适合创建聚集索引;对于经常用于搜索或排序的列,可建立非聚集索引。 3. 避免数据冗余:通过规范化设计减少重复数据,降低数据不一致的...

    day05 11 常见问题 数组索引越界异常

    day05_11_常见问题_数组索引越界异常

    数据库技术与应用 索引-A学习任务书.doc

    1. 描述索引如何提高查询速度,并举例说明。 2. 比较聚集索引和非聚集索引的区别,给出实际应用场景。 3. 设计一个包含多个索引的数据库表,并解释为什么选择这些索引。 4. 在SSMS中,如何查看和分析一个表的索引...

    索引与文件PPT学习教案.pptx

    举例来说,假设我们有一个教师档案表,我们可以根据教师的编号、部门或职称建立索引。如果按照部门建立索引,会形成对应于不同系的子表,每个子表在索引表中都有一个条目,包括子表的开始位置和长度。类似地,按照...

Global site tag (gtag.js) - Google Analytics