| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 大数据 -> MySQL 索引及使用规则(优化sql的关键) -> 正文阅读 |
|
[大数据]MySQL 索引及使用规则(优化sql的关键) |
????????当我们想要对 SQL 进行优化的时候,很大程度上都是围绕着 索引 展开优化的,所以索引在我们对数据库进行优化的过程中至关重要,值得我们重点关注!!!! 本篇文章我们主要围绕以下几个方面展开对 索引 的介绍:
索引 是 MySQL 体系结构中存储引擎层的内容,关于 MySQL 存储引擎可以去看这篇文章:MySQL存储引擎(InnoDB引擎) 一、索引概述什么是索引?????????索引(index)是帮助 MySQL 高效获取数据?的 数据结构(有序)。在数据之外,数据库系统还维护着满足特定查找算法的数据结构,这些数据结构以某种方式引用(指向)数据, 这样就可以在这些数据结构上实现高级查找算法,这种数据结构就是索引。 ? ? ? ? 下面通过一个示例为大家演示一下 索引 的使用:
使用索引有什么优点?缺点呢?
二、索引的结构MySQL?的索引是在存储引擎层实现的,不同的存储引擎有不同的索引结构,主要包含以下几种:? 上述是 MySQL 中所支持的所有的索引结构,接下来,我们再来看看不同的存储引擎对于索引结构的支持情况。?
B 树
????????如果选择
二叉树
作为索引结构,会存在: 顺序插入时,会形成一个链表,查询性能大大降低;大数据量情况下,层级较深,检索速度慢等缺点。如果选择具有自平衡的
红黑树
,虽然可以在顺序插入时最终也会形成一颗平衡的二叉树,但是
由于红黑树也是一颗二叉树,所以也会存在
大数据量情况下,层级较深,检索速度慢的缺点。
????????所以,在 MySQL 的索引结构中,并没有选择二叉树或者红黑树,而选择的是 B+Tree,那么什么是 B+Tree 呢?在介绍?B+Tree 之前,先来介绍一个 B-Tree。 ????????B-Tree,B 树是一种多叉路衡查找树,相对于二叉树,B 树每个节点可以有多个分支,即多叉。以一颗最大度数(max-degree)为 5 (5 阶)的 b-tree 为例,那这个 B 树每个节点最多存储 4 个 key、5 个指针,一旦节点存储的?key?数量到达?5,就会裂变,中间元素向上分裂。:???????? 注意:B-tree 的非叶子节点和叶子节点都会存放数据
B+ 树????????B+Tree 是 B-Tree 的变种,我们以一颗最大度数(max-degree)为 4(4阶)的 b+tree 为例,来看一下其结构示意图: 我们可以看到,两部分:
? ? ? ? B+Tree 与 B-Tree 的最大区别就是:在 B+ 树中,所有数据都会出现在叶子节点,且叶子结点形成一个单向链表,非叶子节点仅仅起到索引数据作用,具体的数据都是在叶子节点存放的。? ????????MySQL 索引数据结构对经典的 B+Tree 进行了优化。在原 B+Tree 的基础上,增加一个指向相邻叶子节点的链表指针,就形成了带有顺序指针的 B+Tree,提高区间访问的性能,利于排序: 注意:这里的 页 / 块 和存储引擎的逻辑结构中的页相对应。 hash????????哈希索引就是采用一定的 hash 算法,将键值换算成新的 hash 值,映射到对应的槽位上,然后存储在 hash 表中。? ????????如果两个(或多个)键值,映射到一个相同的槽位上,他们就产生了 hash 冲突(也称为 hash 碰撞),可以通过链表来解决。? hash 索引的特点:
????????在 MySQL 中,支持 hash 索引的是 Memory 存储引擎。 而 InnoDB 中具有自适应 hash 功能,hash 索引是 InnoDB 存储引擎根据 B+Tree 索引在指定条件下自动构建的。
三、索引的分类在InnoDB存储引擎中,根据索引的存储形式,又可以分为以下两种: 聚集索引必须要有一个,而且也只能有一个,那么聚集索引的选取规则是怎样的呢?
聚集索引和二级索引的具体结构如下:
回表查询: 这种先到二级索引中查找数据,找到主键值,然后再到聚集索引中根据主键值,获取数据的方式,就称之为回表查询。 四、索引的语法1. 创建索引
2. 查看索引
3. 删除索引
五、SQL 性能分析SQL 执行频率????????MySQL 客户端连接成功后,通过 show [session|global] status 命令可以提供服务器状态信息。通过如下指令,可以查看当前数据库的 INSERT、UPDATE、DELETE、SELECT?的访问频次:
????????通过上述指令,我们可以查看到当前数据库到底是以查询为主,还是以增删改为主,从而为数据库优化提供参考依据。 如果是以增删改为主,我们可以考虑不对其进行索引的优化。 如果是以查询为主,那么就要考虑对数据库的索引进行优化了。 慢查询日志????????慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有 SQL 语句的日志。在 MySQL 中默认是没有开启慢查询日志的,若想要开启,则需要在 MySQL 的配置文件(?/etc/my.cnf?)中配置如下信息:
????????配置完毕之后,需要在重新启动 MySQL 后使用以下命令查看是否开启了慢日志查询,并测试查看慢日志文件中记录的信息
检查慢查询日志( /var/lib/mysql/localhost-slow.log ) : profile 详情????????show profiles 能够在做 SQL 优化时帮助我们了解时间都耗费到哪里去了。 查看当前 MySQL 是否支持 profile 操作:
查看当前 MySQL 中 profile 的状态(默认关闭):
开启 MySQL 中的 profile:
????????经过以上指令后,profile 开关就已经打开了,接下来,我们所执行的 SQL 语句,都会被 MySQL 记录,并记录每条 SQL 语句执行的时间,通过以下指令可以查看:
explain 执行计划????????EXPLAIN 或者 DESC 命令可以获取 MySQL 如何执行 SELECT 语句的信息,包括在 SELECT 语句执行过程中表如何连接和连接的顺序。使用格式如下:
Explain 执行计划中各个字段的含义:
六、索引的使用及原则最左前缀法则????????如果索引了多列(联合索引),要遵守最左前缀法则。最左前缀法则指的是查询从索引的最左列开始,并且不跳过索引中的列。如果跳跃某一列,索引将会部分失效(即跳跃之后的字段索引失效)。 接下来我们通过一个示例来更清楚地理解最左前缀法则: ????????例如:我们可以创建一个联合索引:CREATE INDEX index_name ON table_name(index1, index2, index3),这个联合索引中涉及到的三个字段,按顺序分别为:index1,index2,index3,其中?index1 和 index3 是字符串类型,index2 是 int 类型。
????????对于最左前缀法则指的是,查询时,最左变的列,也就是 index1?必须存在,否则索引全部失效。 而且中间不能跳过某一列,否则该列后面的字段索引将失效(而前面连续的几个字段索引依然生效)。下面我们通过几个?SQL?语句的示例看一下具体实现:
全部生效:
index1 和 index2 都生效:
都不生效(无最左侧字段索引):
index1 生效,index3 失效(存在最左侧前缀,但中间有跳跃,跳跃之后的索引字段失效):
全部生效(索引是否生效和编写在 SQL 语句中的位置无关,只看是否存在最左侧的索引字段,且 SQL 语句中的索引字段是否按照联合索引的顺序存在):
注意:这里所说的左侧、右侧、中间跳跃等,是按照索引字段在联合索引中的顺序(即创建索引语句中括号里的顺序)为依据的,并不是索引字段在 SQL 语句中的位置为依据的。 范围查询????????联合索引中,出现范围查询 (>,<),范围查询右侧的列索引失效。
注意:当范围查询使用 >= 或 <= 时,并不存在范围查询的规则,其索引字段是可以生效的,所以,在业务允许的情况下,尽可能的使用类似于 >= 或 <= 这类的范围查询,而避免使用 > 或 < 索引失效的情况1. 不要在索引列上进行运算操作, 否则索引将失效。
2. 字符串类型字段使用时,不加引号,索引将失效。
3. 如果仅仅是尾部模糊匹配,索引不会失效。如果是头部模糊匹配,索引失效。
4. or 连接条件:用 or 分割开的条件, 如果 or 前的条件中的列有索引,而后面的列中没有索引,那么涉及的索引都不会被用到。
5. 数据分布影响:如果 MySQL 自动评估使用索引查询比全表扫描更慢,则不使用索引,而使用全表扫描。 SQL 提示????????SQL 提示,是优化数据库的一个重要手段,简单来说,就是在 SQL 语句中加入一些人为的提示来达到优化操作的目的。 ? ? ? ? 假设?index1 既存在于联合索引中,也存在属于自己的连列索引,我们就可以通过相应的命令人为地决定我们想要使用或禁止的索引:
1. use index : 建议 MySQL 使用哪一个索引完成此次查询(仅仅是建议,mysql 内部还会再次进行评估)
2. ignore index : 忽略指定的索引。
3. ?force index : 强制使用索引。
覆盖索引????????尽量使用覆盖索引,减少 select *。 那么什么是覆盖索引呢? 覆盖索引是指:查询使用了索引,并且需要返回的列,在该索引中已经全部能够找到 。 在查询语句的执行计划?explian 子表中的??extral 字段中可能会显示以下两种数据: 前缀索引????????当字段类型为字符串(varchar,text,longtext 等)时,有时候需要索引很长的字符串,这会让索引变得很大,查询时,浪费大量的磁盘 IO, 影响查询效率。此时可以只将字符串的一部分前缀,建立索引,这样可以大大节约索引空间,从而提高索引效率。? 创建前缀索引的语法如下:
? ? ? ? 我们可以根据索引的选择性来决定,而选择性是指不重复的索引值(基数)和数据表的记录总数的比值,索引选择性越高则查询效率越高, 唯一索引的选择性是1,这是最好的索引选择性,性能也是最好的。查看选择性的公式如下:
下面我们来看一看前缀索引的查询流程: 在具体的业务设计中,我们该遵循怎样的设计原则呢?
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/29 0:38:07- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |