mysql 左连接 怎么走索引_数据库索引、左连接、右连接、等值连接

在MySQL中,主要有四种类型的索引,分别为:B-Tree索引,Hash索引,Fulltext索引(MyISAM 表)和R-Tree索引,本文讲的是B-Tree索引。

一、Mysql索引主要有两种结构:B+Tree索引和Hash索引

(a) Innodb存储引擎 默认是 B+Tree索引

(b) MyISAM 存储引擎 默认是Fulltext索引;

(c)Memory 存储引擎 默认 Hash索引;

Hash索引

mysql中,只有Memory(Memory表只存在内存中,断电会消失,适用于临时表)存储引擎显示支持Hash索引,是Memory表的默认索引类型,尽管Memory表也可以使用B+Tree索引。Hash索引把数据以hash形式组织起来,因此当查找某一条记录的时候,速度非常快。但是因为hash结构,每个键只对应一个值,而且是散列的方式分布。所以它并不支持范围查找和排序等功能。

B+Tree索引

B+Tree是mysql使用最频繁的一个索引数据结构,是Innodb和Myisam存储引擎模式的索引类型。相对Hash索引,B+Tree在查找单条记录的速度比不上Hash索引,但是因为更适合排序等操作,所以它更受欢迎。毕竟不可能只对数据库进行单条记录的操作。

带顺序访问指针的B+Tree

B+Tree所有索引数据都在叶子节点上,并且增加了顺序访问指针,每个叶子节点都有指向相邻叶子节点的指针。

这样做是为了提高区间效率,例如查询key为从18到49的所有数据记录,当找到18后,只要顺着节点和指针顺序遍历就可以以此向访问到所有数据节点,极大提高了区间查询效率。

大大减少磁盘I/O读取

数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点需要一次I/O就可以完全载入。

什么是索引

索引(Index)是帮助数据库高效获取数据的数据结构。索引是在基于数据库表创建的,它包含一个表中某些列的值以及记录对应的地址,并且把这些值存储在一个数据结构中。最常见的就是使用哈希表、B+树作为索引。

一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句的优化显然是重中之重。说起加速查询,就不得不提到索引了。

为什么要使用索引

我们知道,数据库查询是数据库最主要的功能之一。而查询速度当然是越快越好。而当数据量越来越大的时候,查询花费的时间会随之增长。而索引,可以加速数据的查询。因为索引是有序排列的。

举个例子来说,假设我们有一个数据库表Employee,这个表分别有三个字段:name,age,address。假设表中有1000条记录。

假如没有使用索引,当我们查询名为“Jesus”的雇员的时候,即调用:

select name,age,address from Employee where name = 'Jesus';

此时数据库不得不在Employee表中对这1000条记录一条一条的进行判断name字段是否为“Jesus”。这也就是所谓的全表扫描。

而当我们在Employee表上的name字段上创建索引时,当我们查询名为“Jesus”的雇员时,会通过索引查找去查询名为“Jesus”的雇员,因为该索引已经按照字母顺序排列,因此要查找名为“Jesus”的记录时会快很多,因为名字首字母为“J”的雇员都是排列在一起的。通过该索引,能获取到表中对应的记录。

二叉查找树

二叉查找树也称为有序二叉查找树,满足二叉查找树的一般性质,是指一棵空树具有如下性质:

1、任意节点左子树不为空,则左子树的值均小于根节点的值;

2、任意节点右子树不为空,则右子树的值均大于于根节点的值;

3、任意节点的左右子树也分别是二叉查找树;

4、没有键值相等的节点;

平衡二叉树

树形结构是计算机系统里最重要的数据结构。

我们知道,二叉树的查找的时间复杂度是O(log2N),其查找效率与深度有关,而普通的二叉树可能由于内部节点排列问题退化成链表,这样查找效率就会很低。因此平衡二叉树是更好的选择,因为它保持平衡,即通过旋转调整结构保持最小的深度。其查找的时间复杂度也是O(log2N)。

但实际上,数据库中索引的结构也并非AVL树或更优秀的红黑树,尽管它的查询的时间复杂度很低。

为什么平衡二叉树也不适合作为索引

之前说了平衡树的查找时间复杂度是O(log2N),已经很不错了,但还是不适合作为索引结构。那么肯定是有一种更适合作为索引的数据结构。那么这个更适合作为索引的数据结构,难道是查找的时间复杂度更低吗?并不是。这种作为索引的数据结构的查找的时间复杂度也近似O(log2N)。

那为什么平衡二叉树不适合作为索引呢?

索引是存在于索引文件中,是存在于磁盘中的。因为索引通常是很大的,因此无法一次将全部索引加载到内存当中,因此每次只能从磁盘中读取一个磁盘页的数据到内存中。而这个磁盘的读取的速度较内存中的读取速度而言是差了好几个级别。

注意,我们说的平衡二叉树结构,指的是逻辑结构上的平衡二叉树,其物理实现是数组。然后由于在逻辑结构上相近的节点在物理结构上可能会差很远。因此,每次读取的磁盘页的数据中有许多是用不上的。因此,查找过程中要进行许多次的磁盘读取操作。

而适合作为索引的结构应该是尽可能少的执行磁盘IO操作,因为执行磁盘IO操作非常的耗时。因此,平衡二叉树并不适合作为索引结构。

B树的性质

1、定义任意非叶子结点最多只有M个儿子,且M>2;

2、根结点的儿子数为[2, M];

3、除根结点以外的非叶子结点的儿子数为[M/2, M];

4、每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)

5、非叶子结点的关键字个数=指向儿子的指针个数-1;

6、非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];

7、非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;

8、所有叶子结点位于同一层;

B+树

比B树更适合作为索引的结构是B+树。MySQL中也是使用B+树作为索引。它是B树的变种,因此是基于B树来改进的。为什么B+树会比B树更加优秀呢?

B树:有序数组+平衡多叉树;

B+树:有序数组链表+平衡多叉树;

B+树的关键字全部存放在叶子节点中,非叶子节点用来做索引,而叶子节点中有一个指针指向一下个叶子节点。做这个优化的目的是为了提高区间访问的性能。而正是这个特性决定了B+树更适合用来存储外部数据。

MYSQL为什么采用B树而不是B+树

1、 B+树的磁盘读写代价更低:B+树的内部节点并没有指向关键字具体信息的指针,因此其内部节点相对B树更小,如果把所有同一内部节点的关键字存放在同一盘块中,那么盘块所能容纳的关键字数量也越多,一次性读入内存的需要查找的关键字也就越多,相对IO读写次数就降低了。

2、B+树的查询效率更加稳定:由于非终结点并不是最终指向文件内容的结点,而只是叶子结点中关键字的索引。所以任何关键字的查找必须走一条从根结点到叶子结点的路。所有关键字查询的路径长度相同,导致每一个数据的查询效率相当。

3、由于B+树的数据都存储在叶子结点中,分支结点均为索引,方便扫库,只需要扫一遍叶子结点即可,但是B树因为其分支结点同样存储着数据,我们要找到具体的数据,需要进行一次中序遍历按序来扫,所以B+树更加适合在区间查询的情况,所以通常B+树用于数据库索引。

数据库索引采用B+树的主要原因是B树在提高了磁盘IO性能的同时并没有解决元素遍历的效率低下的问题。正是为了解决这个问题,B+树应运而生。

B+树只要遍历叶子节点就可以实现整棵树的遍历。而且在数据库中基于范围的查询是非常频繁的,而B树不支持这样的操作(或者说效率太低)。

正如上面所说,在数据库中基于范围的查询是非常频繁的,因此MySQL最终选择的索引结构是B+树而不是B树。

b+树性质

1.索引字段要尽量的小:通过上面的分析,我们知道IO次数取决于b+数的高度h,假设当前数据表的数据为N,每个磁盘块的数据项的数量是m,则有h=㏒(m+1)N,当数据量N一定的情况下,m越大,h越小;而m = 磁盘块的大小 / 数据项的大小,磁盘块的大小也就是一个数据页的大小,是固定的,如果数据项占的空间越小,数据项的数量越多,树的高度越低。这就是为什么每个数据项,即索引字段要尽量的小,比如int占4字节,要比bigint8字节少一半。这也是为什么b+树要求把真实的数据放到叶子节点而不是内层节点,一旦放到内层节点,磁盘块的数据项会大幅度下降,导致树增高。当数据项等于1时将会退化成线性表。

2.索引的最左匹配特性(即从左往右匹配):当b+树的数据项是复合的数据结构,比如(name,age,sex)的时候,b+数是按照从左到右的顺序来建立搜索树的,比如当(张三,20,F)这样的数据来检索的时候,b+树会优先比较name来确定下一步的所搜方向,如果name相同再依次比较age和sex,最后得到检索的数据;但当(20,F)这样的没有name的数据来的时候,b+树就不知道下一步该查哪个节点,因为建立搜索树的时候name就是第一个比较因子,必须要先根据name来搜索才能知道下一步去哪里查询。比如当(张三,F)这样的数据来检索时,b+树可以用name来指定搜索方向,但下一个字段age的缺失,所以只能把名字等于张三的数据都找到,然后再匹配性别是F的数据了, 这个是非常重要的性质,即索引的最左匹配特性。

这也是经常考察的,比如 我定义了 A,B,C的联合索引,如果 我只传递了 A,B 能走索引吗?答案是能,因为最左侧原理

索引使用注意事项

1,不要滥用索引

①,索引提高查询速度,却会降低更新表的速度,因为更新表时,mysql不仅要更新数据,保存数据,还要更新索引,保存索引

②,索引会占用磁盘空间

2,索引不会包含含有NULL值的列

复合索引只要有一列含有NULL值,那么这一列对于此符合索引就是无效的,因此我们在设计数据库设计时不要让字段的默认值为NULL。

3,MySQL查询只是用一个索引

如果where字句中使用了索引的话,那么order by中的列是不会使用索引的

4,like

like '%aaa%'不会使用索引而like "aaa%"可以使用索引

二、选择索引的数据类型

Mysql支持很多数据类型,选择合适的数据类型存储数据对性能有很大的影响。

(1)越小的数据类型通常更好:越小的数据类型通常在磁盘、内存和cpu缓存中都需要更少的空间,处理起来更快。

(2)简单的数据类型更好:整形数据比起字符,处理开销更小,因为字符串的比较更复杂。在MySQL中,应用内置的日期和时间数据类型,而不是字符串来存储时间;以及用整形数据存储IP地址。

(3)尽量避免NULL:应该制定列为NOT NULL,除非你想存储NULL。在MySQL中,含有空值的列很难进行查询优化,因为他们使得索引、索引的统计信息以及比较运算更加复杂。

三、MySQL常见索引有:主键索引、唯一索引、普通索引、全文索引、组合索引

1,INDEX(普通索引):ALTER TABLE 'table_name' ADD INDEX index_name('col')

最基本的索引,没有任何限制

2,UNIQUE(唯一索引):ALTER TABLE 'table_name' ADD UNIQUE('col')

与“普通索引”类似,不同的就是:索引列的值必须唯一,但允许有空值。

3,PRIMARY KEY(主键索引):ALTER TABLE 'table_name' ADD PRIMARY KEY('col')

是一种特殊的唯一索引,不允许有空值。

4,FULLTEXT(全文索引):ALTER TABLE 'table_name' ADD FULLTEXT('col')

仅可用于MyISAM和InoDB,针对较大的数据,生成全文索引很耗时耗空间

组合索引:ALTER TABLE 'table_name' ADD INDEX index_name('col1','col2','col3')

为了更多的提高mysql效率可建立组合索引,遵循“最左前缀”原则。创建复合索引应该将最常用(频率)做限制条件的列放在最左边,一次递减。组合索引最左字段用in是可以用到索引的。相当于建立了col1,col1col2,col1col2col3三个索引

聚集索引和辅助索引

数据库中的B+Tree索引可以分为聚集索引(clustered index)和辅助索引(secondary index)。上面的B+Tree示例图在数据库中的实现即为聚集索引,聚集索引的B+Tree中的叶子节点存放的是整张表的行记录数据。辅助索引与聚集索引的区别在于辅助索引的叶子节点并不包含行记录的全部数据,而是存储相应行数据的聚集索引键,即主键。当通过辅助索引来查询数据时,InnoDB存储引擎会遍历辅助索引找到主键,然后再通过主键在聚集索引中找到完整的行记录数据

数据库适合创建索引的规则如下:

表的主键,外键应该创建索引;

数据量比较大的表应该创建索引;

经常需要和其他表建立连接,在连接字段应该创建索引;

经常出现在where子句中的字段,应该创建索引。

数据库不适合创建索引的情况:

比较大的文本字段或者长度较长的字段,不适合创建索引;

频繁进行数据操作的表,不适合创建过多的索引,因为额外维护索引表需要更多的开销;

小型表(数据量低于300行)不要建立索引。

参考链接:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/306380.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务技术栈及分享计划

前言上一篇对微服的演变、优缺点进行了概述&#xff0c;对于业务复杂项目&#xff0c;微服务算是比较合适的解决方案&#xff1b;对于咱们开发者来说&#xff0c;有好的解决方案肯定要跟进学习&#xff0c;但不能盲目追崇流行技术&#xff0c;目的还是为了解决问题。这里就把As…

PAT乙级题目——1002写出这个数

问题分析&#xff1a;1.数据比较大&#xff0c;并且输入数据时没有停顿&#xff0c;所有使用字符串来存储数据 string str""; cin>>str;2.使用字符串数组来存储每个数字的拼音 string S[10]{"ling","yi","er","san"…

northstar机器人编程_《机器人构建实战》——导读

前言机器人构建实战机器人是21世纪发展最为迅速、应用前景最为广阔的科学技术领域之一。机器人技术综合运用了基础科学和应用工程技术的最新成果&#xff0c;是一个国家科技发展水平和国民经济现代化、信息化的重要标志&#xff0c;是世界强国重点发展的高技术之一。近年来&…

Linux性能挖潜的隐藏招数:内核CPU亲和性参数调整

作者&#xff1a;李彬&#xff0c;赵雪枫&#xff0c;金融科技工程师&#xff0c;架构师社区特邀作者&#xff01;应用服务性能调优&#xff0c;是每个系统投产前都需要关注的问题&#xff0c;系统及软件层面的调优方法均有大量文章介绍&#xff0c;但在所有招数使出后&#xf…

PAT乙级——1001害死人不偿命的(3n+1)猜想(太简单)

#include<iostream> using namespace std;int main(){int n;int ans0;//记录走过的步数 cin>>n;while(n!1){if(n%20){ans;nn/2;}else{ans;n(3*n1)/2;}}cout<<ans;return 0; }

c4d如何把文字贴在物体表面_C4D在简模上整体和局部贴贴图的方法

引&#xff1a;可能常常碰到一个问题&#xff0c;有了一个模型一个简单的模型&#xff0c;也有了基本材质&#xff0c;想在这个材质上面加点文字内容&#xff0c;比方说一个盒子外面的简单的标签&#xff0c;或者其它&#xff0c;当然你可以用C4D模块中的3D Paint画&#xff0c…

好的重构方法才能摆脱“屎山”

大家好&#xff0c;我是Z哥。最近在整理一些项目&#xff0c;所以相关的文章写的多了些。之前的相关文章有《聊聊单元测试》&#xff0c;感兴趣的话可以点击文末链接去阅读。这次整理项目的时候&#xff0c;做了比较多的codereview和重构。好久没做这么高强度了重构了&#xff…

python中log1p用法_python中logging模块的基本用法

1、logging模块可以跟踪代码的运行记录事件&#xff0c;log信息共内置了5个层级——调试(debug)、信息(info)、警告(warning)、错误(error)、严重错误(critical)2、logging模块用处&#xff1a;控制信息层级&#xff0c;仅记录需要的信息&#xff1b;控制显示或者保存日志信息的…

在 Asp.Net Core 中使用 worker services

ASP.Net Core 3.0 Preview 3 新增了一个 worker services&#xff0c;那什么是 worker services 呢&#xff1f;它如同 windows服务 或者 Linux守护进程 一样的后台服务&#xff0c;在 Visual Studio 中提供了一个专门创建 worker services 的模板&#xff0c;如下图&#xff…

csdn上修改字体的颜色

你喜欢粉色 还是蓝色 还是你喜欢大的 这么大够不够 <font color"pink" size"3">你喜欢粉色</font><font color"blue" size"3">还是蓝色</font><font color"red" size"5">还是你…

react全局状态管理_rxv: 在React中用Vue3的reactivity包实现状态管理。

前言React的状态管理是一个缤纷繁杂的大世界&#xff0c;光我知道的就不下数十种&#xff0c;其中有最出名immutable阵营的redux&#xff0c;有mutable阵营的mobx&#xff0c;react-easy-state&#xff0c;在hooks诞生后还有极简主义的unstated-next&#xff0c;有蚂蚁金服的大…

VS Code 变身约会利器!以码会友,轻松找到心仪的TA!

在韩老师的《Visual Studio Code 权威指南》一书中&#xff0c;我向大家推荐了许多好用的插件&#xff0c;其中也不乏许多摸鱼插件&#xff0c;刷知乎、炒股票、看电影、听音乐、追番、看小说&#xff0c;一应俱全。前不久&#xff0c;韩老师还给大家推荐过一款“小霸王”插件&…

机器学习——常用算法的总结

机器学习常用算法总结 机器学习——常用算法的总结学习方式一、监督式学习&#xff1a;1、分类2、回归补充——线性回归与逻辑回归二、非监督式学习&#xff1a;三、半监督式学习&#xff1a;四、强化学习&#xff1a;算法类似性一、回归算法&#xff1a;二、基于实例的算法三、…

bms中soh计算方式_BMS算法设计之电池SOH介绍(下)

本期咱们继续来聊聊电池包SOH的算法实现&#xff0c;本次主要聊一聊用电化学阻抗谱法&#xff0c;基于模型的估算和机械疲劳的理论方法来实现SOH的估算。上一篇文章没有看到的朋友不用着急&#xff0c;文章中会有上一篇的链接。趁着周末的大好时光&#xff0c;一起来学习下吧&a…

.NET 5 的重大改变:消失的历史技术

在本文中&#xff0c;我们将回顾一些未能进入.NET Core 的历史性.NET 技术。有趣之处在于&#xff0c;这些技术的 API 被复制过来了&#xff0c;这暗示着微软当时在考虑将来在.NET Core 中对它们进行实现。全局程序集缓存全局程序集缓存&#xff08;GAC&#xff09;背后的理论是…

机器学习——决策树学习

机器学习——决策树学习一、什么是决策树二、决策树的学习过程特征选择&#xff1a;决策树生成&#xff1a;剪枝&#xff1a;三、决策树的一个具体的实例导入数据python strip() 函数和 split() 函数的详解及实例数据处理提取到训练集中的标签给数据的每一列添加上标签&#xf…

微软:Excel公式是世界上使用最广泛的编程语言

喜欢就关注我们吧&#xff01;文|一君微软近日推出了一项 Excel 公式构建的新功能 LAMBDA&#xff0c;正则测试阶段。LAMBDA 允许使用 Excel 自身的公式语言自定义功能&#xff0c;而过去&#xff0c;Excel 中需要通过 JS 等语言编写自定义函数。同时&#xff0c;LAMBDA 还可以…

tcp unity 图片_用 Unity 做个游戏(七) - TCP Socket 客户端

前言这真的是最后一篇有关基础框架的文章了&#xff01;写到这里已经第七篇了orz之前的其实还是挺枯燥的&#xff0c;都是些基础方面的东西&#xff0c;并看不到什么有趣的内容可能是我把事情想的太复杂了吧&#xff0c;所有东西都想做到能力范围内的最好&#xff0c;尤其是这些…

机器学习——文件的读取

机器学习——文件的读取(一).txt文件的读取(二)excel文件读取操作(一).txt文件的读取 txt的链接 链接&#xff1a;https://pan.baidu.com/s/1fIAUdCDTpR7TiqLHZtx1yg 提取码&#xff1a;0929 python strip() 函数和 split() 函数的详解及实例 一直以来都分不清楚strip和split…

理解C#中的闭包

1、 闭包的含义首先闭包并不是针对某一特定语言的概念&#xff0c;而是一个通用的概念。除了在各个支持函数式编程的语言中&#xff0c;我们会接触到它。一些不支持函数式编程的语言中也能支持闭包&#xff08;如java8之前的匿名内部类&#xff09;。在看过的对于闭包的定义中&…