意见箱
恒创运营部门将仔细参阅您的意见和建议,必要时将通过预留邮箱与您保持联络。感谢您的支持!
意见/建议
提交建议

聚焦索引对非聚集索引有何影响,如何分析得出

来源:恒创科技 编辑:恒创科技编辑部
2023-12-16 01:46:59
这篇文章给大家分享的是聚焦索引对非聚集索引有何影响,如何分析得出。小编觉得挺实用的,因此分享给大家做个参考,文中的介绍得很详细,而要易于理解和学习,有需要的朋友可以参考,接下来就跟随小编一起了解看看吧。

话题


聚焦索引对非聚集索引有何影响,如何分析得出

非聚集索引定义:非聚集索引也是一个B树结构,与聚集索引不同的是,B树的叶子节点存的是指向堆或聚集索引的指针。你真的理解了吗??你能举出例子吗??其实本节最终想表达的就是这个意思,定义太长,我们抽象一点来定义并得出最终结论,请往下看。

聚集索引对非聚集索引影响

关于聚集索引和非聚集索引的概念、原理、创建都不会再叙述,若对此不太了解请参其他的详细介绍。

首先我们创建测试表

USE SQLStudy
GO
CREATE TABLE [dbo].[Test](
[ID] [int] NOT NULL,
[First] [nchar](10) NULL,
[Second] [nchar](10) NULL
)
GO

接下来我们再来创建测试数据

INSERT INTO [SQLStudy].[dbo].[Test] ([ID],[First],[Second])
SELECT 1,'First1','Second1'
UNION ALL
SELECT 2,'First2','Second2'
UNION ALL
SELECT 3,'First3','Second3'
UNION ALL
SELECT 4,'First4','Second4'
UNION ALL
SELECT 5,'First5','Second5'
GO

紧接着我们对表上的First和Second列创建聚集索引,如下

CREATE NONCLUSTERED INDEX [IX_MyTable_NonClustered] ON [dbo].[Test] (
[First] ASC,
[Second] ASC
)

此时我们来同时运行两个查询,看看其执行计划【注】:上一篇已经说过,请启用包括实际执行的计划。

SELECT ID
FROM [dbo].[Test] WHERE [First] = 'First1' AND [Second] = 'Second1'
SELECT Second
FROM [dbo].[Test] WHERE [First] = 'First1' AND [Second] = 'Second1'
GO

此时我们看到的执行计划如下:

通过上述毫无疑问我们可以得出结论:查询1是利用的全表扫描,而查询2利用的非聚集索引查找。我们应该对于这个结论没有任何怀疑,因为要第二个查询的Second列在此之前已经创建额非聚集索引,而对于查询1中的ID则没有,所以会造成查询1的全表扫描,而查询2则是非聚集索引查找。

下面我们对表上的列ID创建聚集索引。

CREATE CLUSTERED INDEX [IX_MyTable_Clustered] ON [dbo].[Test] (
[ID] ASC
)

此时我们再来运行如下查询:

SELECT ID
FROM [dbo].[Test] WHERE [First] = 'First1' AND [Second] = 'Second1'
SELECT Second
FROM [dbo].[Test] WHERE [First] = 'First1' AND [Second] = 'Second1'
GO

此时再来看看查询执行计划:

通过上述我们对列ID创建了聚集索引,我们肯定能立马知道两者都是利用索引查找,确实没错,但是,但是你发现没有,睁大眼睛看看,我们明明在列ID上创建的是聚集索引,理论上应该是聚集索引查找才对啊,这就是我们本文所需要讨论的问题。

问题探讨

我们将问题进行如下概述,当我们在列上创建聚集索引时且查询返回该列,同时查询条件是创建了非聚集索引的列,此时对于创建了聚集索引的列的查询执行计划则是非聚集索引查找,这其中到底发生了什么?

实际发生的情况是非聚集索引内部引用了聚集索引, 当聚集索引被创建后在表中的数据会按照物理逻辑进行排序,当聚集索引没有被创建时此时非聚集索引指向的表中的数据并最终返回数据,但是一旦聚集索引创建了此时非聚集索引则会重建从而此时指向的是聚集索引,说到这里对于园友CareySon对于非聚集索引的描述:非聚集索引也是一个B树结构,与聚集索引不同的是,B树的叶子节点存的是指向堆或聚集索引的指针。概括的非常精准,若创建了聚集索引此时非聚集索引的指针则指向的是聚集索引,否则此时指向的是堆也就是表中的数据。所以此时在这种情况下,当查询创建了聚集索引的列时是进行了非聚集索引查找。

至此,我们可以得出结论:当在检索的列上创建了聚集索引时(仅仅返回创建聚集索引的列),此时查询不会使用聚集索引查找来检索结果而是使用非聚集索引查找来检索结果。

总结

个人觉得对于一个定义出来之前我们得首先抛出这样一个问题,如上述非聚集索引的定义:非聚集索引也是一个B树结构,与聚集索引不同的是,B树的叶子节点存的是指向堆或聚集索引的指针。初次看到这句感觉没什么,泛泛而谈,感觉似乎理解了,当遇到这样的问题时却不知所措,其实就是对定义理解的不够深入或者说不够透,当一个定义出来时你能举出这个定义的例子或者场景,那可能才算是真正了解了。本节我们到此结束,对于SQL这一系列会秉着简短的内容,深入的理解来讲解,同时也会循序渐进讲讲查询性能问题,由抛出问题到最终解决问题才算是收货多多。


以上就是关于“聚焦索引对非聚集索引有何影响,如何分析得出”的相关知识,感谢各位的阅读,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注恒创科技,小编每天都会为大家更新不同的知识。
上一篇: SQL中having和where的使用有何不同,如何应用好 下一篇: SQL中怎么求中位数,SQL语句的写法是怎样