暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

堆表、回表、索引覆盖、主键索引、聚集索引等一些知识点

原创 aisql 2021-10-21
2169

mysql 一定是索引组织表,且主键索引一定也是聚集索引。 所以 mysql 二级索引的叶子节点一定存放的是主键的值。
受mysql 影响,我也一度以为sql server 二级索引叶子节点也是存储的主键索引。但实际不一定是。
下面通过一个例子来慢慢探究一下

先构造一个测试数据,并创建一个二级索引

create table testIndex (id int, tname varchar(50) ) insert into testIndex select ROW_NUMBER() over(order by name),name from sys.objects where type = 'U' create index ix_testIndex on testIndex(tname)

然后,我们写一个查询,强制走二级索引

select * from testIndex with(index(ix_testIndex)) where tname like 'ad%'

1851304850d06b8bb6b20e4b.webp

从实际计划中可以看到。因为二级索引 ix_testIndex 没有 我需要的所有列,所以需要回表拿更多数据,但从图中看到,这次回表走的是heap堆表回表拿数据.

我们再创建一个主键索引,将这个主键索引创建为非聚集的

ALTER TABLE testIndex ADD CONSTRAINT [PK_testIndex] PRIMARY KEY NONCLUSTERED (ID)

看一下现在的索引情况

22.webp

然后再看上一个语句

select * from testIndex with(index(ix_testIndex)) where tname like 'ad%'

再看执行计划
33.webp

回表还是走的堆表

我们继续,创建一个聚集索引

create CLUSTERED index clx_testIndex on testIndex(id)

看一下现在的索引
44.webp

继续执行

select * from testIndex with(index(ix_testIndex)) where tname like 'ad%'

55.webp

从执行计划中看到。这次索引没有回表。在二级索引上拿到了所有需要的数据,完成了索引覆盖,那就可以证明二级索引ix_testIndex 叶子节点存储的就是聚集索引id列的值。

再改一下语句 强制走主键索引

select * from testIndex with(index(PK_testIndex)) where tname like 'ad%'

从执行计划中可以看出,由于主键索引只有 id列,聚集也只有id列,所以主键索引拿不到tname列 需要回表, 这次回表就是回的聚集索引了。

66.webp

所以sql server与mysql 还是有很大我区别。

1、sql server 主键索引只是一个约束,只有当它是聚集索引的时候,二级索引叶子节点才是主键的值
2、没有聚集索引的时候, 就是堆表,而不是索引组织表
3、有聚集索引的时候,就变成了索引组织表
4、二级索引叶子节点,存储的是聚集索引列的值。

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论