绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
《高性能SQL调优精要与案例解析》深入体味“索引”
2019-11-26 15:00:41


 《读韵会 》课:深入体味“索引”

说说,为什么课,先讲索引,我们做项目无非就是把一个网站,一个功能,一个APP做上线,这个项目上线后会遇到各种bug,常见,影响用户体验的,无明挨骂的,不痛不痒,就是运行速度,慢!更甚之,卡!!

这时候,作为技术明星,一定不是扯皮,而是用专业的能力解决他,并告之,升级或增加服务器在一定程度上也可以起到缓解作用。

需要解决,慢甚至卡的问题,就要深入的懂得“索引”的原理。

「数据库」和「数据库索引」这两个东西是在程序开发领域应用为广泛的两个概念,熟练使用数据库和数据库索引是开发人员在行业内生存的必备技能。

使用索引很简单,只要能写创建表的语句,就肯定能写创建索引的语句,要知道这个世界上是不存在不会创建表的程序员的。

然而, 会使用索引是一回事, 而深入理解索引原理又能恰到好处使用索引又是另一回事,这完全是两个天差地别的境界。很大一部分程序员对索引的了解仅限于到“加索引能使查询变快”这个概念为止。

在各主流关系库中,占据SQL调优半壁江山的、重要的核心技术之一——索引(Index)。

《高性能SQL调优精要与案例解析》一书中,闫老师也再三强调索引对SQL调优的重要性,但是,学习和掌握SQL调优技术,只看案例和解决问题的具体方法,而不学习和掌握SQL调优相关的基础知识,终都是徒劳的,学习任何知识和技能都是一样的,我们必须做到知其然,更要知其所以然,才能做到融会贯通,活学活用,进而将SQL调优技术掌握到炉火纯青的地步。



就SQL调优的分析和解决问题的思路、方法和步骤来说,各关系库几乎完全一样,只是具体命令、方法和形式有所差别而已。

本文中,我们将对各主流关系库的索引机制进行简要阐述,以帮助各位同学深入理解和掌握作为SQL调优核心技术之一的索引,进而为掌握SQL调优打下坚实基础。关系库中,索引类型不止一种,而不同关系库、同一关系库不同版本之间,也会或多或少的存在差别。



                                                                                         

下面,我们仅就各关系库中应用广泛的B*tree索引做简要介绍和论述。

1. Oracle B*tree索引:Oracle中B*Tree索引的组织结构图在《高性能SQL调优精要与案例解析》一书中均有详细描述,此处不再赘述。需要强调的是,Oracle中B*Tree的非叶级块(Non-leaf Level Block )中,存储的只有索引列的键值(单列索引的列值或多列索引的列值组合)大值和指向下一级非叶级块或叶级块(Leaf Level Block)的指针(Pointer),这里的指针,也就是块的物理地址,即文件号+块号。Oracle中B*Tree的叶级块中,则存储了索引列的键值+ROWID(数据行的物理地址,即数据行所在文件号+块号+槽号),这样,通过B*Tree中的键值和ROWID值,就能很容易的先通过索引中的键值得到相应数据行的ROWID,再用ROWID找到表中相应的数据行。而Oracle中,表对应段(Segment)中的数据行,则存储于堆结构(Heap),具体见《高性能SQL调优精要与案例解析》。

而值得一提的是,Oracle中还有一种特殊的表组织结构,那就是索引组织表(IOT),该类表虽然在Oracle中应用不多,但在其他关系库中,的确应用很广,只不过名称和细节不同而已,具体继续看下面的内容。

2.  Mysql B*Tree索引:大家可能也知道,Mysql数据库是一种插件数据库,也就是其各个存储引擎可以方便的进行插拔(Plugin和Unplugin),因此,Mysql中也有多种存储引擎同时存在。因为本文不是专门讲述Mysql存储引擎的,因此,我们就拿应用广的Innodb引擎为例来进行介绍和说明。Innodb中的B*Tree索引(Mysql中又称Index为key),与Oracle中的B*Tree不同。

Mysql的Innodb引擎中,根据索引具体的组织结构,又可分为簇索引(Clustered Index或Primary Key Index)和非簇索引(Secondary Index),Mysql中创建一个Innodb类型的表时,系统会自动为表的主键创建一个簇索引,如果没有为该表指定一个主键,系统会自动选定该表的一个非空索引作为主键,如果不存在非空索引,系统也会自动创建一个隐式主键,总之,Innodb表的主键必不可少。

事实上,Innodb表中的数据都存储于前述的簇索引中,具体说,簇索引是一个B*Tree结构,只是叶级页(Leaf Level Page)内除了存储簇索引的键值外,还存储了表中所有其他列的数值,因此,Innodb表中的数据都是逻辑有序的。

Innodb表的非簇索引(Secondary Index),其叶级块中并不包含表中相应数据行的物理地址(类似Oracle中数据行的ROWID),而是包含了表的簇索引中相应数据行的主键键值,因此,Innodb表中,通过非簇索引查找数据行,一般要经历两次键值查找,次在非簇索引上查找该索引的键值,通过非簇索引键值得到簇索引的相应键值后,再到表的簇索引上查找,终才能找到真正要查找的数据行。

这里强调的是,Innodb表的簇索引不是个可选项,说它是一种数据的组织方式更贴切。Innodb表簇索引的组织结构和Oracle中的索引组织表类似。

3.  SQL Server B*Tree索引:SQL Server数据库,美国微软的拳头产品之一,有时人们俗称之为MSSQL,目前国内外有着相当的市场占有率。MSSQL的B*Tree索引与Mysql的B*Tree类似,也分为簇索引(Clustered Index)和非簇索引(Nonclustered Index)。

但与Mysql的B*Tree索引不同的是,MSSQL中表的簇索引并非是强制的,也就是,你在MSSQL数据库中创建一张表,该表是一张堆表,也就是其对应的段(MSSQL中应该叫分区(Partition))是以堆的形式组织和存储的,有关堆的概念,《高性能SQL调优精要与案例解析》一书中也有详细论述。MSSQL中,如果你为堆表创建了一个簇索引,那么,该表中的数据都被移到被创建的簇索引的叶级页(Leaf Level Page)中,并且以该簇索引键值的顺序排序、组织和存储,原来的堆不再存在,如果你选择不为该堆表创建簇索引,那么,该表就会一直以堆的形式存在。

MSSQL中的非簇索引,根据簇索引的存在与否,其内部组织方式分为两种情况,当表上存在簇索引时,非簇索引的叶级页中存储簇索引的键值,也就是不存在指向表中相应数据行物理地址的指针;如果表上不存在簇索引,非簇索引叶级页中就会存储指向表中相应数据行物理地址的指针(MSSQL中叫这个指针为Rid)。

MSSQL中,不管表是否存在簇索引,通过非簇索引查找数据行的行为称为书签查找(Bookmark Lookup)。MSSQL中,一般将主键作为表的簇索引来进行创建和使用。由此可知,MSSQL中的簇索引,在组织结构上与Oracle中的索引组织表及MYSQL中的簇索引相似。

4.  Postgresql B*Tree索引:Postgresql数据库,作为强大的开源关系库,因其内部机制及风格与Oracle非常相似,一直享有“免费版的Oracle”的美誉,也是关系库家族中,与Oracle相似度高的一款关系库。如上所述,既然Postgresql很多方面与Oracle如此相似,那么,Postgresql中B*Tree索引的组织结构及特点也不例外。Postgresql中的B*Tree索引和Oracle中很相似,同样,也没有Mysql和MSSQL中簇索引的概念和说法。

但相似归相似,两者还是存在很大不同,Postgresql的表和索引等数据库对象,都是以单独的文件形式组织和存储;8k大小的数据页也与Oracle中的块不同;Postgresql中MVCC与Oracle中的实现机制也有较大差别。

简单说,Postgresql表中数据的前影像数据和当前版本存储在一起,废弃的前影像数据需要定期通过相关机制或命令进行清除。此外,因为Postgresql的B*Tree索引中并不存在数据的版本信息,所以,SQL调优的索引覆盖技术并不能完全避免计划中的回表操作,无论索引列是否能全部覆盖SQL语句中的所有列,有时都需要回表操作来确认相关数据行的具体版本信息。

虽然,Postgresql9.2版本中引进了scan-only scans操作,也只能在有些场景中省去回表操作,但得访问表的VM文件以确认是否需要回表操作。如果VM文件中数据行的相应位(Bit)为unset状态,则还是需要回表操作,因此,鉴于前述机制上的诸多局限,该技术的实际价值并没那么大,对写少读多的业务场景,也许会有更大的价值。

以上对各流行关系库的Index机制和特性进行了简要的介绍和论述,以希望对各位同学更好的理解和掌握SQL调优技术有所帮助,也有助于自己参考和研究。

闫书清老师,从事数据库行业已有20余年,除了自己著作的书籍《高性能SQL调优精要与案例解析》,随着技术社区的进化,也在ITPUB技术栈建立了自己的栈点,更实时的更新他的研究成果,欢迎大家观摩、提问、交流,探讨。

世上没有套路,有的,只是适应发展!



有索引问题,请教大佬,请扫码


分享好友

分享这个小栈给你的朋友们,一起进步吧。

读韵会
创建时间:2019-10-10 11:26:20
a,时光冉然,精读好书,沉淀精华人生。 b,用平静定力的声音,诠释技术“简单的玄妙”,意为用在妙处的平淡技术。 c,技术已发展到瓶颈,其,“应用”的功夫还不够深,让我们一起慢慢品味技术的本质原理,使您的工作事半功倍。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

栈主、嘉宾

查看更多
  • 小尾巴鱼
    栈主
  • wojiuzhuai
    嘉宾

小栈成员

查看更多
  • youou
  • 余辛未
  • miaoxy
  • 栈栈
戳我,来吐槽~