当我谈论索引时,大家经常会问我在复合非聚集索引里,列的顺序是否重要?简单来说:“看情况”。我们来具体看下为啥“看情况”……

单例查找(Singleton Lookups)

当在你的表上有进行单例查找的查询时,在复合非聚集索引里列的顺序真的不重要。假设下列查询:

-- Without a supporting Non-Clustered Index we have to scan the complete Clustered Index
SELECT AddressID FROM Person.Address
WHERE StateProvinceID = 79 AND City = 'Bothell'
GO

现在你可以在StateProvinceIDCity,或CityStateProvinceID创建非聚集索引:

-- Create a supporting Non-Clustered Index
CREATE NONCLUSTERED INDEX idx_Test ON Person.Address(StateProvinceID, City)
GO-- SQL Server performs a Non-Clustered Index Seek operation in combination with a Seek Predicate
SELECT AddressID FROM Person.Address
WHERE StateProvinceID = 79 AND City = 'Bothell'
GO-- Change the column ordering
CREATE NONCLUSTERED INDEX idx_Test ON Person.Address(City, StateProvinceID)
WITH (DROP_EXISTING = ON)
GO-- The column ordering doesn't matter in the Non-Clustered Index
SELECT AddressID FROM Person.Address
WHERE StateProvinceID = 79 AND City = 'Bothell'
GO

这里非聚集索引里的列的顺序真的不重要,因为SQL Server在执行计划里直接进行非聚集索引查找操作(在与查找谓语集合里):

范围扫描(Range Scans)

当我们讨论在表上的范围扫描时,这里你检索一组数据,就是另一回事了。假设你执行下列查询:

SELECT AddressID FROM Person.Address
WHERE StateProvinceID BETWEEN 10 AND 12 AND City = 'Bothell'
GO

这次,支持的非聚集索引,你有2个方法:

  • StateProvinceID和City列上的非聚集索引
  • City和StateProvinceID列上的非聚集索引

我们先用第一个方法:

-- Create a supporting Non-Clustered Index
CREATE NONCLUSTERED INDEX idx_Test ON Person.Address(StateProvinceID, City)
GO

这个情况下,如你在执行计划里所见,SQL在StateProvinceID列上对查询进行非聚集索引查找操作,对于City列要计算剩余谓语的值:

这真的不是个完美的执行计划,因为你读取了比你请求更多的数据。但有基于StateProvinceID列上的排序作为引导列, City作为随后列,这是唯一可能的行为,如你从下图所见:

现在我们尝试交换下列来创建非聚集索引:City作为引导列,StateProvinceID作为第二列:

-- Change the column ordering in the Non-Clustered Index
CREATE NONCLUSTERED INDEX idx_Test ON Person.Address(City, StateProvinceID)
WITH (DROP_EXISTING = ON)
GO-- Non-Clustered Index Seek on StateProvinceID *without* a Residual Predicate on column City
SELECT AddressID FROM Person.Address
WHERE StateProvinceID BETWEEN 10 AND 12 AND City = 'Bothell'
GO

当你再次执行你的查询,你会看到SQL Server再次执行了非聚集索引查找操作。但这次对于你的查询,“没有”剩余谓语(Residual Predicate)。

因为你物理上读取的刚好是你逻辑上请求的数据。但这个现在这么可能呢?那就看看下面的图:在非聚集索引里数据是如何排序的:

如你所见,现在的数据按City预先排,在每个City组里,你会有在StateProvinceID列的排序。因此你可以直接获得逻辑请求的数据——不用进一步剩余谓语(Residual Predicate)的值计算就可以返回值。

小结

当你要进行范围扫描时——在复合非聚集索引里列的顺序重要的!在多次交流会上我经常提到:SQL Server里的一切几户都与索引有关,索引本身就会预排序数据!没别的!理解SQL Server是否可以直接查找逻辑请求的数据,你也需要在你的心中想象下如何使如何预排序的,你如何通过有效预排序数据来访问它。

希望这篇文章可以让你更好的理解在非聚集索引里,列排序如何影响查找操作。

感谢关注!

转载于:https://www.cnblogs.com/lykbk/p/hgfhffhfhfhfhhfhf678786886687.html

复合非聚集索引里列的顺序的重要性相关推荐

  1. 聚集索引与非聚集索引的总结

    一.索引简介 众所周知,索引是关系型数据库中给数据库表中一列或多列的值排序后的存储结构,SQL的主流索引结构有B+树以及Hash结构,聚集索引以及非聚集索引用的是B+树索引.这篇文章会总结SQL Se ...

  2. mysql聚集索引和非聚集索引的区别_聚集索引与非聚集索引的总结

    一.索引简介 众所周知,索引是关系型数据库中给数据库表中一列或多列的值排序后的存储结构,SQL的主流索引结构有B+树以及Hash结构,聚集索引以及非聚集索引用的是B+树索引.这篇文章会总结SQL Se ...

  3. Mysql --聚集索引与非聚集索引

    转自:https://www.cnblogs.com/s-b-b/p/8334593.html 一.索引简介 众所周知,索引是关系型数据库中给数据库表中一列或多列的值排序后的存储结构,SQL的主流索引 ...

  4. 聚集索引和非聚集索引的区别底层_数据库-索引相关

    一.什么是索引 在数据库中,索引的含义与日常意义上的"索引"一词并无多大区别(想想小时候查字典),它是用于提高数据库表数据访问速度的数据库对象. 总而言之,索引是一个排序的列表,在 ...

  5. SQLSERVER聚集索引与非聚集索引的再次研究(下)

    上篇主要说了聚集索引和简单介绍了一下非聚集索引,相信大家一定对聚集索引和非聚集索引开始有一点了解了. 这篇文章只是作为参考,里面的观点不一定正确 上篇的地址:SQLSERVER聚集索引与非聚集索引的再 ...

  6. 唯一聚集索引上的唯一和非唯一非聚集索引

    在上篇文章里,我讨论了唯一和非唯一聚集索引的区别.我们已经知道,SQL Server内部使用4 bytes的uniquifier来保证非唯一聚集索引行唯一.今天我们来看下唯一聚集索引上,唯一和非唯一非 ...

  7. 索引键的唯一性(3/4):唯一聚集索引上的唯一和非唯一非聚集索引

    在上篇文章里,我讨论了唯一和非唯一聚集索引的区别.我们已经知道,SQL Server内部使用4 bytes的uniquifier来保证非唯一聚集索引行唯一.今天我们来看下唯一聚集索引上,唯一和非唯一非 ...

  8. 聚集索引和非聚集索引详解 (zhuang)

    SQL中.聚集索引和非聚集索引有何区别? 聚集索引和非聚集索引的根本区别是表记录的排列顺序和与索引的排列顺序是否一致,聚集索引表记录的排列顺序与索引的排列顺序一致,优点是查询速度快,因为一旦具有第一个 ...

  9. SQL中的索引知识点总结(聚集索引、非聚集索引)

    SQL里的索引(index)知识: 索引分为聚集索引和非聚集索引,数据库中的索引类似于一本书的目录,在一本书中通过目录可以快速找到你想要的信息(例如字典里按照拼音或部首查找).索引的目的是提高系统性能 ...

最新文章

  1. Java 集合 — HashMap
  2. Count and Say leetcode java
  3. 11g cursor_sharing 参数说明
  4. EasyRecovery——一款专业的数据恢复软件
  5. STS下载教程(include官网无法下载解决方案)
  6. 7.arm汇编 bic和orr指令
  7. 小众软件android,七款优秀的小众软件,每款都是装逼神器!
  8. Cloud Chou's Tech Blog编译相关
  9. 小爱同学指令大全_小爱同学指令
  10. i.MX6ULL GPIO
  11. 杯子倒水问题 -python
  12. 论文笔记:Eye In-Painting with Exemplar Generative Adversarial Networks
  13. 【SugerTangYL】UART串口通信 Verilog
  14. PC端自动化工具开发:Pywinauto的安装及使用
  15. Android大厂面试题系统分类从基础到困难(BATJ,蚂蚁金服,字节跳动,网易云,QQ音乐...)
  16. Mysql MATCH() AGAINST() (MATCH AGAINST)
  17. STM32循迹小车系列教程(三)—— 使用灰度传感器循迹
  18. Airtest 的常用库——poco
  19. 电子邮件系统哪个好?分享2022电子邮件系统排名大全及主要功能
  20. 1169 糖果(差分约束)

热门文章

  1. 精通机器学习的5本免费电子书(5 free e-books for machine learning mastery)
  2. 使用GLSL实现雾化的效果
  3. Redis命令——Keys相关
  4. Git pull[push] 不用每次输入用户名和密码
  5. 十一课堂|通过小游戏学习Ethereum DApps编程(4)
  6. 2018年1月29日
  7. CentOS LAMP一键安装网站环境及添加域名
  8. Linux下添加PATH环境变量
  9. CentOS 升级PHP
  10. Emacs基础命令整理 - Unplugged - 博客频道 - CSDN.NET