【JAVA今法修真】 第七章 洞天风云起,索引混乱平
作者:互联网
您好,我是南橘,万法仙门的掌门,刚刚从九州世界穿越到地球,因为时空乱流的影响导致我的法力全失,现在不得不通过这个平台向广大修真天才们借去力量。你们的每一个点赞,每一个关注都是让我回到九州世界的助力,兄弟萌来为我注入修为吧!关注WX号:南橘ryc 。在公众号上,除了可以看到云小霄的照片,李小庚的画像也很快出炉哦。
等我回去以后,大家都是万法仙门的长老,我会给大家数不尽的天材地宝,人人如龙,全民飞升
通辽州,自古修时代分割天下九州以来,三十六洞天占了七个,七十二福地占了十四个,是九州大陆上数一数二的富贵州。而随着今法到来,以一家一姓为主占据洞天福地的时代已然过去,云中洞天服务慢慢取代了传统的不可移动的固定洞天。作为通辽州传统强宗,占据了大半洞天福地的万法仙门,更是阔气到可以给每一个筑基期圆满的弟子配发专属的云洞天。
“师弟,你们云霄殿没有自己的私有云吗?”后勤部金丹期执事林建成凝重地盯着李小庚递过来的玉牌。
“当然有啊。”李小庚笑了笑,打了个响指。
云中洞天之所以以云中为名,便是因为它如同天上的云朵一样可以伴随修士左右,同时在隐藏的时候又能够如云雾一般散去。
精心装饰过的洞府,琳琅满目的修真典籍和天材地宝整齐摆放在超豪华16核32G私人云中洞天器内,周围环绕的淡淡金色光晕象征着DDoS高防特性,镶嵌在正中心的两颗符文石证明它自带通辽云海两洲三中心灾备。
至今还用着十年前突破金丹期后门派分配的只有双核4G服务器的林建成嘴角抽了抽:“师弟已经有了这么好的东西,就没必要再来领这种单核的云中洞天了吧。”
“师兄此言差矣。”李小庚再一个响指(可以设定一些条件作为洞天启动关闭的扳机),洞天慢慢变淡直到完全消失,然后抱拳道:“长者赐,不敢辞,毕竟是宗门派发,我必将好好珍惜。”
“…”后勤部一直是整个万法仙门,亦或是大部分仙门里最有“价值”的部门,因为很多家中富裕或者长辈出手阔气的弟子都不会再来领取宗门发放的制式装备,这个时候,这些装备就成为了后勤部门的奖金。
林建成见李小庚完全没有放弃领取的意思,只能悻悻的放下本来马上到手的装备,一本正经的说道:“好吧,既然你选择领取云中洞天,我也按宗门的规矩考考你几个问题。”
“还请师兄赐教。”
“什么是覆盖索引?”
1、覆盖索引
如果一个索引包含了满足SQL语句中字段与条件的数据,那么它就叫做覆盖索引。
覆盖索引只需要在一棵索引树上就能获取SQL所需的所有列数据,无需回表,速度更快。
既然提到了回表,那么我先讲一下什么叫回表。
回表的流程:
- 第一步在辅助索引 B+树中检索 , 到达其叶子节点获取对应的主键
- 第二步使用主键在主索引 B+树中再执行一次 B+树检索操作, 最终到达叶子节点即可获取整行数据。
我们能很清晰的看出来,左边的是聚集索引,右边的是辅助索引,上图告诉我们如果回表查询的话,会先在辅助索引中找到主键值,再去聚集索引中找到全部的信息。在InnoDB 中,表数据文件本身就是按 B+Tree 组织的一个索引结构,这棵树的叶点data 域保存了完整的数据记录。这个索引的 key 是数据表的主键,因此 InnoDB 表数据文件本身就是主索引(聚集索引)。
聚集索引:
- 如果定义了主键,那么主键就是聚集索引
- 如果没有定义主键,那么第一个not NULL unique列是聚集索引
- 如果都没有,则InnoDb会创建一个隐藏row-id作为聚集索引
而辅助索引就是我们平常用到的非主键索引。
“哦,师弟的sql基础很不错嘛,那你可知咱们万法仙门制式的云中洞天的数据结构是什么吗?”
“是B+树!它使用了B+树!”李小庚开始玩起烂梗。
“那你说说为什么要使用B+树吧,顺便解释一下B+树的查询方式。”林建成好像并没有看懂李小庚的梗:“当然,师弟不要觉得我在难为你,毕竟作为云霄殿的弟子,我这个做师兄的对你的期望自然也会高一些,相信宗门的师长们也是这样想的。”
“好的师兄,没问题师兄。”李小庚依旧满脸灿烂的笑容。
2、B+树
首先,B+树是B树的一种扩展,如下图所见,在B+树内,非叶子节点不再存储数据,仅仅存在索引,而叶子节点负责存储具体的数据,且最底层的数据直接之间从左到右是按顺序分布,形成一个双链表的结构。也就是说,各层节点中的索引数据均是下一层相应节点中的最大或者最小的索引的复写。
B+树最核心的特点:
- 只有叶子节点保存数据
- 多路非二叉
- 增加了相邻接点的指向指针
- B+树的非叶子节点的每一个关键字对应一个指针,而关键字则是子树的最大,或者最小值
通过这些特点,我们其实可以总结出B+树的优点:
- B+树相比B树的存储效率更高。B+树其实是多级索引,这种结构与Redis中跳跃表是非常的相似(以后会讲),最下一层是所有关键码的全集,因此可以把此层形成顺序的双链链表,正因为在B+树里面非叶层节点不需要存储额外的指向磁盘的指针,所以相比之前的B树,B+树存储效率更高。
- B+树的高度更小,也就是说B+树的检索效率更高
- B+树支持范围检索,因为叶子节点形成有序链表,所以能够很好的支持范围查找。
- 插入和删除更为方便,其实流程和B树类似,但B+树里面,关键码的个数和子节点的个数是对等的,所以从记忆角度来说,B+树更方便记忆使用,而B树则需要时刻注意节点数和关键码的对应关系。
- 时间复杂度低,因为从宏观上可以做到一次排除一半的数据,并且在写入时也没有进行其他额外的数据查找性工作,所以对于b树来说,其读写的时间复杂度都是O(log2n)。
当然,相比于B树,其实B+树还是有一些缺点的,比如只有叶子节点才存放数据,所以不会出现那种灵机一动,这也就意味着查找B+树,就必须到叶子节点才能返回结果。
B+树的查询方式:
- 1 从root出发查询到叶节点。
- 2 从叶节点的最左侧出发,进行顺序查找,同时也可使用进行范围查找。
“那么,下一个问题。”林建成一边把玩着云中洞天的客户端,一边阴惴惴地盯着李小庚:“师弟的理论基础还真是牢固啊,不过接下来,师兄想考验一下你的动手能力,师弟不介意吧。”
“当然是师兄说什么就怎么办啦~”李小庚脸上的笑容也越发灿烂了,可他笑的越开心,林建成内心就越发不爽。
“那好。”林建成捏着洞天的手突然发出青绿色的光芒,紧接着,洞天客户端(类似一个水晶球的样子)里忽然仿佛被风神之诗席卷了一般。
“我屮艸芔茻!”李小庚从一脸严肃,不苟言笑,看起来毫无私心的林建成的手里接过洞天客户端:“师兄您这是让我自己修复好它?”
“是的,李小庚师弟,这个洞天已经属于你了,但是在使用它之前,我对你的最后一个考验就是将它复原。”
“你知道为什么你永远比不过我吗?”就像阳光穿过黑夜,如同黎明悄悄划过天边,二师姐罗妍忽然一把夺过李小庚手中的客户端,打量了片刻:“因为你自卑,懦弱,和我斗了那么多年后发现斗不过我,就只能去刁难我的师弟。”
“师弟你记住,一个强者最重要的不是有多么高深的法力,也不是多么厉害的法宝,而是有着稳定的情绪,清晰的思路,坚定的自信,和永不言弃的精神,而不是一个只能挥刀向弱者的勇士”。
“说完了吗?永远有着吃不完的天材地宝,用不尽的数据资源,和最新式法器的大小姐。”林建成冷哼了一声:“的确,我不如你,我的基础款飞剑比不过你的剑阵,我的社区版编译器斗不过你的专业版,我的一品金丹自然也比不过你的一品龙纹加强版。你可以一直在研究院燃烧经费,而我只能在后勤部捞捞油水,补贴我那可怜至极的小工坊。甚至,我可能永远都没办法奢侈到使用这位筑基期师弟的云中洞天。”
“你们云霄殿的背景太大,我惹不起,还请罗大小姐和李师弟大人有大量,这个云中洞天就当做赔罪送给弟了,告辞!”林建成一伸手从云雾中召唤出自己的云中洞天,然后转手丢给李小庚,随后剑诀一捏,飘然而去。
“师姐?这?”李小庚属实是被震惊到了。
“没事,一个手下败将而已,只是没想到把你牵扯进来了,他的东西你拿着就行,在万法仙门里,他不敢找你麻烦。”罗妍在研究所呆久了,回忆了片刻才艰难对李小庚的露出了一个笑容:“这个云中洞天你要不要尝试着修复一下?”
“可以,我来试试吧。”李小庚摸索了一下:“优化索引的方式就行了吧?”
“思路正确,林建成并没有做的太过分,所以你尝试优化一下索引就行了。”
3、利用覆盖索引优化sql
我们通过覆盖索引,查询想要的数据字段都是索引键值的一部分,直接存放在索引的子叶层级,不需要通过辅助索引来一次回表查询,效率很高。
覆盖索引不仅仅只包含你写在WHERE条件内的字段,而且还包含所有SELECT 需要的字段,以及在GROUP BY 或ORDER BY 子句内的字段。那么我可以怎么通过覆盖索引来优化我们的sql呢?
1、全表查询SQL优化、可以把需要查询的列加入索引>select count(name) from user;
比如这个很常见的查询数量的sql,我们就可以把user加入索引,这样就可以免去回表查询
ALERT TABLE user ADD index index_name(name);
2、列表查询回表优化
select id,name,sex from user where name='fawaikuangtuzhangsan' ALERT TABLE user ADD index index_name_sex(name,sex);
将单列索引(name)升级为联合索引(name, sex),即可避免回表。
3、其他方式都差不多,都是通过将所有查询的列加入覆盖索引以达成防止回表的目的,当然,这个东西需要看情况用,不然长长的索引列也会带来存储上的压力
覆盖索引可以完美的解决二级索引回表查询问题。但是前提是一定得注意查询时候索引的最左侧匹配原则
4、最左匹配原则
最左优先,以最左边的为起点任何连续的索引都能匹配上。如果是联合索引,那么key也由多个列组成,同时,索引只能用于查找key是否存在(相等),遇到范围查询 (>、<、between、like左匹配)等就不能进一步匹配了,后续退化为线性查找。
建立了联合索引abc
ALTER TABLE `ryc` ADD INDEX index_a_b_c(`a`,`b`,`c`);
select * from ryc where a = '1' and b = '2' and c = '3' select * from ryc where b = '2' and a = '1' and c = '3' select * from ryc where c = '3' and b = '2' and a = '1' select * from ryc where a = '3' and b = '2' select * from ryc where a = '3'
这些情况搜索都不影响查询结果,因为它们都是从最左边开始,同时因为Mysql中有查询优化器,会自动优化查询顺序 ,当然我们最好可以按顺序写,最少看起来都舒服一些
select * from ryc where b = '3' and c = '2' select * from ryc where b = '3'
而这些没情况有从最左边开始,最后查询没有用到索引,用的是全表扫描
select * from ryc where a = '3' and c = '2'
如果是这种情况呢,就只命中了a的索引,c还是得老老实实的去扫描
如果遇到了><之类的范围查询,在范围查询之前,如果满足最左匹配原则,那么就可以按索引走,在范围查询之后的就不管了
如:select * from ryc where a = '3' and b = '2' and c<7
这种情况就满足了最左匹配原则的查询
select * from ryc where a > 3 and b = '2' and c<7
这种情况就只有a能够查索引了,bc都需要全表扫描了
如果是order by排序的情况,那么又有一些不同
select * from ryc order by b,c,a limit 10;
大家觉得这种情况能不能用到索引?
很遗憾,没有,不过这个 filesort 并不是说通过磁盘文件进行排序,而只是告诉我们进行了一个排序操作而已,当然,using filesort不一定引起mysql的性能问题。但是如果查询次数非常多,那么每次在mysql中进行排序,还是会有影响的。
select * from ryc order by a limit 10; select * from ryc order by a,b limit 10; select * from ryc where a =1 order by b,c limit 10;
标签:JAVA,洞天,今法,ryc,查询,索引,李小庚,修真,select 来源: https://blog.csdn.net/ryc1995/article/details/122176850