索引覆盖与覆盖索引的深入探究

【1】索引覆盖

【1.1】索引覆盖的概念

  在我的理解中,什么是索引覆盖?就是说,你的所有查询条件中,每个条件CBO都愿意去扫描索引来查询数据(无论是单列索引还是复合索引均可),然后根据索引扫描/查找的结果可以获取到我们要的结果集。

  然后最后非聚集索引会根据不同where条件走的索引获取到叶子节点数据(也就是聚集索引键值),这个时候就获取到了 聚集索引值+本身索引列的值。

  最后再拿不同where条件获取到的聚集索引值做等值比较匹配,均相等的就是我们想要的数据。这个也避免了回表去从实际存储数据的数据页去找数据。

【1.2】索引覆盖实践(MSSQL)

use master;
create table test(id int,num int,num1 int);
create clustered index CIX_id on test(id);
create index IX_num on test(num);
create index IX_num1 on test(num1);
--create a test data, 10000 rows
;with temp as (
select 1 as id,5 as num,10 as num1
union all
select id+1,num+5,num1+10 from temp
where id<10000
)
insert into test select * from temp option(maxrecursion 0);

结果:

  

如上图,我们可以看到,并没有回表,优化器直接分别根据 num 和 num1 去读取这2列上的索引。

然后获取到 (1) 聚集索引键值+num    (2)键值索引键值+num1

最后,直接对比匹配相等的聚集索引值(因为查出来的聚集索引键值并不一定保证是有序的《也可以理解成这个时候出来的聚集索引键值就是一个堆结果集》,所以这里MSSQL自动用了更优秀的匹配算法:HASH匹配,因为它是等值查询非常快的方法之一);

【1.3】索引覆盖实践(MYSQL)

【2】覆盖索引

【2.1】覆盖索引的概念

  这就是我们经常说的覆盖索引和索引覆盖,大多数人并没有细细区分它们。

  那到底什么叫覆盖索引呢?我的理解是,一个索引包含了所有我们要查的值。

【2.2】覆盖索引实践(MSSQL)

use master;
create table test1(id int,num int,num1 int,num2 int);
create clustered index CIX_id on test1(id);
create  index IX_num on test1(num);
create  index IX_num1_2 on test1(num1,num2);
--create a test data, 10000 rows
;with temp as (
    select 1 as id,5 as num,10 as num1, 11 as num2
    union all
    select id+1,num+5,num1+10,num2+11 from temp
    where id<10000
)
insert into test1 select * from temp option(maxrecursion 0);

  (1)复合索引列带来的覆盖索引

    

  因为复合索引中已经包含了 num2的值,所以直接就可以查询出来了。

     

  同理,因为 id 是聚集索引,已经在(num1,num2) 复合索引的叶子节点里了,所以也满足覆盖索引的特性(包含索要查询的所有数据),这里也没有回表,直接在索引查询中就搞定了。

  同理单列索引、include包含,这些带来的效果都是一样的。

 

原文地址:https://www.cnblogs.com/gered/p/12210055.html

时间: 2024-11-08 09:41:38

索引覆盖与覆盖索引的深入探究的相关文章

一文总结分析聚集索引、非聚集索引、覆盖索引的工作原理!

「数据库」和「数据库索引」这两个东西是在服务器端开发领域应用最为广泛的两个概念,熟练使用数据库和数据库索引是开发人员在行业内生存的必备技能. 使用索引很简单,只要能写创建表的语句,就肯定能写创建索引的语句,要知道这个世界上是不存在不会创建表的服务器端程序员的.然而, 会使用索引是一回事, 而深入理解索引原理又能恰到好处使用索引又是另一回事,这完全是两个天差地别的境界(我自己也还没有达到这层境界).很大一部份程序员对索引的了解仅限于到"加索引能使查询变快"这个概念为止. 1.为什么要给表

索引的分类--B-Tree索引和Hash索引

索引是存储引擎用来快速查找记录的一种数据结构,按照实现的方式有不同的种类,想B-Tree索引,hash索引,空间数据索引和全文索引等.下面主要说一下B-Tree索引和Hash索引.人们在谈论索引的时候如果没有特别说明,一般指的是B-Tree索引.B-Tree索引是使用B-Tree数据结构来存储索引的.B-Tree通常意味着所有的值是按照顺序存储的.B-Tree树有如下几个特征:⑴树中每个结点至多有m 棵子树:⑵若根结点不是叶子结点,则至少有两棵子树:⑶除根结点之外的所有非终端结点至少有[m/2]

聚集索引与非聚集索引的用法举例与使用注意

聚集索引 用法举例 小明需要查找一个人的姓名,知道他在公司的营销部门的1010办公室的4号座位.这个时候如果需要专门为小明建一个聚集索引表就是,以公司部门表内部门名称排序,再以房间总表序号排序,最后以房间详细表的座位表排序,这样就可以最快的找到他要找的人 聚集索引类似于一个字典,我们知道拼音来寻找字,首先我们知道字音节的首字母,从按a-z排序的字典中找到这个字首字母所在的区域,再从这个区域找到韵母所在的区域,当然韵母在字典中也有顺序,最后就可以找到我们想要的字了 注意事项 限制原则 每个表只能有

聚集索引与非聚集索引

转自:聚集索引和非聚集索引(整理) 官方说法: 聚集索引 一种索引,该索引中键值的逻辑顺序决定了表中相应行的物理顺序. 聚集索引确定表中数据的物理顺序.聚集索引类似于电话簿,后者按姓氏排列数据.由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引.但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样. 聚集索引对于那些经常要搜索范围值的列特别有效.使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻.例如,如果应用程序执行 的一个查询经

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

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

聚集索引和非聚集索引

聚集索引 一种索引,该索引中键值的逻辑顺序决定了表中相应行的物理顺序.  聚集索引确定表中数据的物理顺序.聚集索引类似于电话簿,后者按姓氏排列数据.由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引.但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样.    聚集索引对于那些经常要搜索范围值的列特别有效.使用聚集索引找到包含第一个值的行后,便可以确保包含后续索引值的行在物理相邻.例如,如果应用程序执行 的一个查询经常检索某一日期范围内的记录,则使用聚集索

聚集索引和非聚集索引(整理)

From : http://www.cnblogs.com/aspnethot/articles/1504082.html 官方说法: 聚集索引 一种索引,该索引中键值的逻辑顺序决定了表中相应行的物理顺序.  聚集索引确定表中数据的物理顺序.聚集索引类似于电话簿,后者按姓氏排列数据.由于聚集索引规定数据在表中的物理存储顺序,因此一个表只能包含一个聚集索引.但该索引可以包含多个列(组合索引),就像电话簿按姓氏和名字进行组织一样.    聚集索引对于那些经常要搜索范围值的列特别有效.使用聚集索引找到

索引访问方法及索引优化

要了解索引访问方法,首先要知道索引的结构. 1.表和索引的结构  页 页是sql server存储数据的基本单位,大小为8kb,可以存储表数据.索引数据.执行计划数据.分配位图.可用空间信息.页是sql server可以读写的最小I/O单位.即便是读取一行数据,它也要把整个页加载到缓存并从缓存中读取数据. 区 区是由8个连续页组成的分配单元. 堆 堆是指不含聚集索引的表,它的数据不按任何顺序进行存储. 联系一个堆中的数据的唯一结构是被称为索引分配映射(IAM)的一个位图页,当扫描对象时,SQl

mysql重复索引、冗余索引、未使用索引的定义和查找

1.冗余和重复索引 mysql允许在相同列上创建多个索引,无论是有意还是无意,mysql需要单独维护重复的索引,并且优化器在优化查询的时候也需要逐个地进行考虑,这会影响性能.重复索引是指的在相同的列上按照相同的顺序创建的相同类型的索引,应该避免这样创建重复所以,发现以后也应该立即删除.但,在相同的列上创建不同类型的索引来满足不同的查询需求是可以的. 冗余索引和重复索引有一些不同,如果创建了索引(a,b),再创建索引(a)就是冗余索引,因为这只是前面一个索引的前缀索引,因此(a,b)也可以当作(a

36. SQL -- 聚集索引和非聚集索引(2)

关于聚集索引与非聚集索引的讨论: A.区别: 聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个 聚集索引存储记录是物理上连续存在,而非聚集索引是逻辑上的连续,物理存储并不连续. B.关于索引的几个问题: DEMO 分析: 一个学生表student,里面是学生号id,学生姓名,学生所在城市ID,学生成绩(总分). · 问:如果想按姓名查询,如何做优化? · 答:在姓名字段上建立索引. · 问:建立什么类型的索引? · 答:建立非聚集索引. · 问:为什么? · 答:一般有范围查询的需求,可