Mysql索引优化解决方案

news2024/11/23 10:59:29

一、索引介绍

1、什么是索引

索引就是帮助mysql高效获取数据的数据结构

mysql 除了存储数据,还有数据结构,我们可以通过数据结构的查找算法快速找到数据,这种数据结构就是索引。类似于 字典中的目录,帮助我们快速查找数据。

2、建立索引与否的区别

1、不建索引:数据库会做全表扫描,一条条遍历,直到找到数据
比如查找mysql这个单词,会先从A 找到M 再从A 找到Y。。效率低

2、建索引:会直接定位到 M Y 数据上,效率高

3、索引数据结构

常见的索引数据结构

  1. B-Tree(Myisam 普通索引)

  2. 二叉树
    典型二叉树:大的在右边 小的在左边,比如查找15李四,会拿15和10比较 比10大找右边节点 。
    缺点: 当数据插入时,如果一直往右边插入,会形成链表,查询效率低。
    在这里插入图片描述

  3. B+Tree(Innodb 普通索引)、

  4. Hash(memory 存储引擎)等

问:为了减少IO,索引树会一次性加载吗?

如果数据量很大,索引的大小也会很大
当我们利用索引查询时候,是不可能将全部几个G的索引都加载进内存的,逐一加载每一个磁盘页,因为磁盘页对应着索引树的节点。

问:Hash索引与B+树索引的区别

  • Hash索引不能进行范围查询,而B+树可以
  • Hash索引不支持联合索引的最左侧原则,而B+树可以
  • Hash索引不支持 ORDER BY 排序,而B+树可以
  • InnoDB不支持哈希索引,而B+树可以

问:InnoDB数据存储结构

数据页

4、索引的优劣

优势:

  1. 提高数据查询效率,降低IO成本
  2. 通过索引进行排序,降低数据排序成本 降低 CPU消耗

劣势:

  1. 索引也是一张表,保存了主键和索引的字段,并指向实体表的记录,所以索引占用空间
  2. 降低表的更新速度 对数据进行增删改的时候,mysql不仅要更新数据 也更新索引的表

5、索引使用场景

  1. 主键自动建立唯一索引
  2. 查询中与其它表关联的字段,外键关系建立索引
  3. 频繁作为查询条件的字段应该创建索引(where 后面的语句)
  4. 多字段查询下倾向创建组合索引
  5. 查询中排序的字段 order by
  6. 查询中统计或者分组字段 count()、 group by
  7. DISTINCT 字段需要创建索引

不推荐建立索引

  1. 表记录太少
  2. 有大量重复数据的列上不要建立索引
  3. Where条件里用不到的字段不建立索引
  4. 避免对经常更新的表创建过多的索引
  5. 删除不再使用或者很少使用的索引
  6. 不要定义冗余或重复的索引

6、索引分类

6.1、主键索引

设置主键 自动建立主键索引

创建主键索引语法: alter table 表名 add primary key (字段);
删除主键索引语法: alter table 表名 drop primary key;

6.2、唯一索引

给表字段设置唯一索引后,该字段列值唯一 不能重复
创建唯一索引语法

alter table 表名 add unique 索引名(字段)
create unique index 索引名 on 表名(字段)

删除唯一索引:

drop index 索引名 on 表名;

6.3、普通索引

只是索引,没有其他约束

单独创建和删除单值索引

alter table 表名 add index 索引名(字段);
create index 索引名 on 表名(字段);

删除普通索引

drop index 索引名 on 表名;

6.4、复合索引

一个索引包含多个列

创建复合索引

create index 索引名 on 表名(字段1,字段2);
 alter table 表名 add index 索引名(字段,字段2);

删除复合索引

drop index 索引名 on 表名; 


6.5、全文索引

只有字段的数据类型为 char、varchar、text 及其系列才可以建全文索引。 对于大文本数据字段,like模糊查询效率极低,全文索引效率很高。

创建全文索引

create fulltext index content_tag_fulltext
    on fulltext_test(字段1,字段2);

删除全文索引

drop index content_tag_fulltext
    on fulltext_test;

使用全文索引

select * from fulltext_test 
    where match(content,tag) against('xxx xxx');

注意:

  • match() 函数中指定的列必须和全文索引中指定的列完全相同,否则就会报错,无法使用全文索引
  • 需要配置最小搜索长度,mysql配置文件修改,修改后 删除全文索引并重新创建
[mysqld]
innodb_ft_min_token_size = 1
ft_min_word_len = 1
  • 需要添加 修饰符搜索 (常见词不会搜索出的问题)
    在这里插入图片描述
select * test where match(content) against('a*' in boolean mode);
  • 对于中文,可以使用 MySQL 5.7.6 之后的版本,或者第三方插件。

问:为什么使用组合索引

比如使用组合索引 a b c 相当于 创建 三个索引:a ,ab ,abc。
比单独设置三个索引,节省空间。

物理实现方式分类

6.5、聚簇索引

Innodb使用的是 聚簇索引 mysql主键就是聚簇索引

聚簇索引:每张表的主键构建 B+Tree ,叶子节点存放整张表的行记录数,因此数据也是索引的一部分,每个表只能有一个聚簇索引。如果没有主键则使用非空的唯一索引字段

优点:

  • 数据访问快:索引和数据在一个 B+Tree中,比非聚簇索引快
  • 聚簇索引对于主键的排序查找和范围查找速度非常快。

缺点:

  • 插入速度严重依赖于插入顺序,按照主键的顺序插入是最快的方式,对于InnoDB表,我们一般都会定义一个自增的ID列为主键。
  • 更新主键的代价很高,因此,对于InnoDB表,我们一般定义主键为不可更新。
    -非聚簇索引需要两次索引查找,第一次找到主键值,第二次根据主键值找到行数据。

6.6、非聚簇索引(二级索引、辅助索引)

在聚簇索引上创建的索引叫辅助索引,非聚簇索引访问数据总是需要二次查找(在有主键的表上创建普通索引等,再创建的索引就是非聚簇索引)。

辅助索引叶节点存在的是主键值,通过非聚簇索引先找到主键值,再通过主键值找到数据行的数据页,再通过数据页找到数据行。

问:主键索引是聚集索引还是非聚集索引?

在Innodb下主键索引是聚集索引,在Myisam下主键索引是非聚集索引

问:什么是覆盖索引

索引列+主键包含SELECT 到 FROM之间查询的列。
就是 查询的字段 都在索引中。

二、性能分析

1、mysql常见瓶颈

SQL中对大量数据进行比较、关联、排序、分组时CPU的瓶颈。

实例内存满足不了缓存数据或排序等需要,导致产生大量的物理IO。查询数据时扫描过多数据行,导致查询效率低。

2、explain

使用 explain 关键字可以模拟优化器执行sql查询语句,从而知道 mysql 如何处理SQL语句的,可以用来分析查询语句或表结构的性能瓶颈
作用:

  1. 表的读取顺序

  2. 哪些索引可以使用

  3. 数据读取操作的操作类型

  4. 那些索引被实际使用

  5. 表之间的引用

  6. 每张表有多少行被优化器查询

explain 使用:

explain + sql

在这里插入图片描述

3、explain 重要字段

1、id

  • select查询的序列号,表示查询中执行select子句或操作表的顺序。
  • id相同时,执行顺序由上至下。
  • id不同,如果是子查询,id的序号会递增,id值越大优先级越高,则先被执行。
  • id相同和不同都存在时,id相同的可以理解为一组,从上往下顺序执行,所有组中,id值越大,优先级越高越先执行。

2、select_type

  • SIMPLE :简单的 select 查询,查询中不包含子查询或者UNION。
  • PRIMARY:查询中若包含任何复杂的子部分,最外层查询则被标记为Primary。
  • DERIVED:在FROM列表中包含的子查询被标记为DERIVED(衍生),MySQL会递归执行这些子查询, 把结果放在临时表里。
  • SUBQUERY: 在SELECT或WHERE列表中包含了子查询。

3、table

显示这一行的数据是关于哪张表的。

4、type

  • System:表只有一行记录(等于系统表),这是const类型的特列,平时不会出现,这个也可以忽略不计。

  • Const:表示通过索引一次就找到了,const用于比较primary key或者unique索引。因为只匹配一行数据,所以很快,如将主键置于where列表中,MySQL就能将该查询转换为一个常量。

  • eq_ref:唯一性索引扫描,对于每个索引键,表中只有一条记录与之匹配。常见于主键或唯一索引扫描。

  • Ref非唯一性索引扫描,返回匹配某个单独值的所有行。本质上也是一种索引访问,它返回所有匹配某个单独值的行,然而,它可能会找到多个符合条件的行,所以他应该属于查找和扫描的混合体。

  • Range:只检索给定范围的行,使用一个索引来选择行。key 列显示使用了哪个索引
    一般就是在你的where语句中出现了between、<、>、in等的查询这种范围扫描索引扫描比全表扫描要好,因为它只需要开始于索引的某一点,而结束语另一点,不用扫描全部索引。

  • Index:Full Index Scan,index与ALL区别为index类型只遍历索引树。这通常比ALL快,因为索引文件通常比数据文件小。也就是说虽然all和Index都是读全表,但index是从索引中读取的,而all是从硬盘中读的。

  • All:Full Table Scan,将遍历全表以找到匹配的行

从最好到最差依次是:system>const>eq_ref>ref>range>index>All
一般来说,最好保证查询能达到range级别,最好能达到ref。

5、possible_keys

显示可能应用在这张表中的索引,一个或多个。查询涉及到的字段上如果存在索引,则改索引将会被列出来,但不一定会被查询实际使用上(索引会失效)。

6、key

实际用到的索引

7、ref

显示索引的哪一列被使用了。哪些列或常量被用于查找索引列上的值。

8、rows

rows列显示MySQL认为它执行查询时必须检查的行数。一般越少越好。

9、extra

一些常见的重要的额外信息:

  • Using filesort:MySQL无法利用索引完成的排序操作称为“文件排序”。
  • Using temporary:Mysql在对查询结果排序时使用临时表,常见于排序order by和分组查询group by。
  • Using index:表示索引被用来执行索引键值的查找,避免访问了表的数据行,效率不错。
  • Using where:表示使用了where过滤。

三、查询优化

1、索引失效

  1. 最佳左前缀法则:如果索引了多列,要遵循最左前缀法则,指的是查询从索引的最左前列开始并且不跳过索引中的列。
    如:该表设置了复合索引,索引列的顺序是 sname,age、score 。
    红色框中都是用了索引,绿色没有使用索引,因为 where条件顺序和 复合索引的顺序一致(当复合索引三个列 都在where 条件可以不按顺序,否则必须按照顺序不能跳过索引列),所以红色框中的三条语句中where字段都使用到了索引。
    而绿色的sql没有sname 查询字段,因此没有使用索引,如果 条件是 where sname and score 则只有 sname 使用了索引 score 没有使用。

因为最佳左前缀法则 中复合索引的所有列 必须和索引列顺序一致(当复合索引三个列 都在where条件可以不按顺序,否则必须按照顺序不能跳过索引列),并且不能跳过 否则后面的索引列失效


在这里插入图片描述

  1. where 中:不在索引列上做任何计算、函数操作,会导致索引失效而转向全表扫描,from 之前没事

  2. 不能使用索引中范围条件右边的列。
    因为 age做了范围查询,所以 第三个索引列 score 不生效,
    就算是 where sname and score and age > 0 也是如此第三个索引列 score 不生效
    在这里插入图片描述

  3. Mysql在使用不等于时无法使用索引会导致全表扫描
    在这里插入图片描述

  4. like以通配符开头会使索引失效导致全表扫描。like “明%” 是可以使用索引的
    在这里插入图片描述

  5. 字符串不加引号索引会失效。
    在这里插入图片描述

  6. 使用or连接时索引失效。
    在这里插入图片描述

总结:
在这里插入图片描述

建议:

  • 对于单值索引,尽量选择针对当前查询字段过滤性更好的索引
  • 对于组合索引,当前where查询中过滤性更好的字段在索引字段顺序中位置越靠前越好
  • 对于组合索引,尽量选择能够包含在当前查询中where子句中更多字段的索引。
  • .尽可能通过分析统计信息和调整query的写法来达到选择合适索引的目的。
  • 将需要范围查询的字段 从组合索引中去掉
    如索引 a b c: where a =1 and b >1 order by c desc 会导致 C 索引失效,那么把 b从组合索引中删除。

2、排序优化(分组优化同理)

组合索引 a b c :在 where 和 order by 和 group by 组合使用 组合索引,满足最左前缀。
在这里插入图片描述

  • 尽量避免使用Using FileSort方式排序。
  • where子句中如果出现索引范围查询会导致order by索引失效。
  • order by语句使用索引最左前列或使用where子句与order by子句条件组合满足索引最左前列。

案例:
将需要范围查询的字段 从组合索引中去掉
如索引 a b c: where a =1 and b >1 order by c desc 会导致 C 索引失效,那么把 b从组合索引中删除。

3、关联查询优化

mysql 会把小结果集的为 驱动表,所以大表最好加上所以
左连接:会左边全表查询,那么右表为驱动表 建议加上索引
右连接:会右边全表查询,那么左表为驱动表 建议加上索引
在这里插入图片描述

四、慢查询日志

1、简介

MySQL的慢查询日志是MySQL提供的一种日志记录,他用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中。可以由它来查看哪些SQL超出了我们最大忍耐时间值。

2、使用

  • 查看是否开启:
show variables like '%slow_query_log%';
  • 开启日志:
set global slow_query_log = 1;
  • 设置时间:
set global long_query_time = 1;
  • 查看时间:
 SHOW VARIABLES LIKE 'long_query_time%';
  • 查看超时的sql记录日志:Mysql的数据文件夹下
    5.5\Data\设备名称-slow.log
    在这里插入图片描述

注意:调优场景下,一般启动改参数,调优结束 关闭
慢查询日志支持将日志记录写入文件,开启慢查询日志会或多或少带来一定的性能影响。

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

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

相关文章

Netty核心组件EventLoop源码解析

源码解析目标 分析最核心组件EventLoop在Netty运行过程中所参与的事情&#xff0c;以及具体实现 源码解析 依然用netty包example下Echo目录下的案例代码&#xff0c;单我们写一个NettyServer时候&#xff0c;第一句话就是 EventLoopGroup bossGroup new NioEventLoopGroup(…

html2canvas将页面dom元素内容渲染成图片保存至本地

html2canvas:https://html2canvas.hertzen.com/configuration/ github:https://github.com/niklasvh/html2canvas 效果 代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compa…

VR直播丨颠覆性技术革命,新型直播已经到来

细数当下最火热的营销手段&#xff0c;首先浮现脑海的无疑是“直播”。前有罗永浩、李佳琦&#xff0c;后有刘畊宏和东方甄选&#xff0c;直播如日中天&#xff0c;俨然成了大众足不出户就能休闲娱乐的重要途径。 而随着虚拟现实在“十四五规划”中被列入“建设数字中国”数字…

一文了解GPU并行计算CUDA

了解GPU并行计算CUDA一、CUDA和GPU简介二、GPU工作原理与结构2.1、基础GPU架构2.2、GPU编程模型2.3、软件和硬件的对应关系三、GPU应用领域四、GPUCPU异构计算五、MPI与CUDA的区别一、CUDA和GPU简介 CUDA&#xff08;Compute Unified Device Architecture&#xff09;&#xf…

Java 常用 API

文章目录一、Math二、System三、Object1. toString() 方法2. equals() 方法四、Arrays1. 冒泡排序2. Arrays 常用方法五、基本类型包装类1. Integer2. int 和 String 相互转换3. 字符串中数据排序4. 自动装箱和拆箱六、日期类1. Date2. SimpleDateFormat3. Calendar4. 二月天一…

(四十七)大白话表锁和行锁互相之间的关系以及互斥规则是什么呢?

今天我们接着讲&#xff0c;MySQL里是如何加表锁的。这个MySQL的表锁&#xff0c;其实是极为鸡肋的一个东西&#xff0c;几乎一般很少会用到&#xff0c;表锁分为两种&#xff0c;一种就是表锁&#xff0c;一种是表级的意向锁&#xff0c;我们分别来看看。 首先说表锁&#xf…

如何使用Arsenal快速部署功能强大的Bug Bounty工具

关于Arsenal Arsenal是一个功能强大且使用简单的Shell脚本&#xff08;Bash&#xff09;&#xff0c;该工具专为漏洞赏金猎人设计&#xff0c;在该工具的帮助下&#xff0c;我们可以轻松在自己环境中安装并部署目前社区中功能最为强大的网络侦查工具、漏洞扫描工具和其他安全研…

企业活动直播如何设置VIP观看席?

阿酷tony / 2023-2-28 / 长沙 / 多图内容企业活动直播如何设置VIP观看席&#xff1f;有意思吧&#xff0c;直播也能设vip席位。在直播间可以分设尊享嘉宾席、特邀VIP以及观众席三个区域&#xff0c;为企业提供多种用户接待模式&#xff0c;不仅能为嘉宾营造尊享VIP体验&#xf…

Git学习(1)pro git阅读

目录 目录&#xff1a; 1. 起步 2. Git 基础 3. Git 分支 4. 服务器上的 Git 5. 分布式 Git 第一章 1.3 Git是什么 1.6运行git前的配置 该开源图书网站 Git - Book (git-scm.com) 目录&#xff1a; 1. 起步 1.1 关于版本控制1.2 Git 简史1.3 Git 是什么&#xff1f;1…

Fedora系统安装KubeVela

话不多说直接看命令 Docker安装 Vela安装需要先安装Docker sudo yum -y install docker只需这行命令便可以自动添加 yum和dnf理论上都能成功&#xff0c;但是很看网速&#xff0c;&#xff0c;&#xff0c;实践证明yum是最好的。 如果发生报错mirrors trieds大概率就是网速超…

[oeasy]python0096_游戏娱乐行业_雅达利_米洛华_四人赛马_影视结合游戏

游戏娱乐行业 回忆上次内容 游戏机行业从无到有 雅达利 公司 一枝独秀并且带领 行业 发展起来 雅达利公司 优秀员工 乔布斯 在 朋友 帮助下完成了《pong》 Jobs 黑了 Woz 一部分收入 然后拿着钱 去印度禅修了 游戏行业 会如何继续 呢&#xff1f;?&#x1f914; 灵修 乔布…

常见损失函数Loss Function的选择(regression problem)

损失函数Loss Function的设计是机器学习模型的核心问题&#xff0c;一般情况下函数式子会分成两项&#xff1a;衡量预估值和目标间的差距、正则项式。其中正则项式子一般用于衡量模型的复杂度&#xff0c;可以避免模型过拟合&#xff08;奥卡姆剃刀原理&#xff09;。 另一部分…

【Node.js】MySQL数据库的第三方模块(mysql)

mysql安装操作MySQL数据库的第三方模块&#xff08;mysql&#xff09;通过第三方模块&#xff08;mysql2&#xff09;连接到MySQL数据库mysql插入数据mysql插入数据的便捷方式mysql更新数据mysql更新数据的便捷方式mysql删除数据安装操作MySQL数据库的第三方模块&#xff08;my…

Direct IO

目录 一、基本介绍 二、使用方法与Demo 三、O_DIRECT 与 O_SYNC 一、基本介绍 如上图所示&#xff0c;普通的 IO 读写&#xff0c;会先将内容保存在缓冲区中&#xff0c;文件落盘需要调用 fflush 、fsync 等方法。 而 DirectIO 是无缓冲 IO&#xff0c;&#xff0c;使用无缓…

>>数据管理:DAMA简介「考试和续期」

关于DAMA,这里就不再多做描述,可以参考以前写的一些简介或官方介绍。下面就考试再做一些详细介绍。 1 区别 CDGA:数据治理工程师(Certified Data Governance Associate),“DAMA中国”组织的数据治理方面的职业认证考试。 CDGP:数据治理专家(Certified Data Governa…

数学小课堂:无穷小(用动态和极限的眼光看世界)

文章目录 引言I 极限1.1 柯西对极限的认知1.2 极限准确的定义1.3 数列极限的定义1.4 函数极限的定义1.5 无穷小(特殊的极限)1.6 定量和逆向思维1.7 认知升级的过程引言 身处于渐变世界的人类,难以理解瞬间突变。 老师的作用,就是用大白话,把数学语言所写的知识,翻译成大…

基于ANN以使用有监督和无监督的学习将其分为不同的类别或识别模式(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 人工神经网络&#xff08;ANN&#xff09;在包括技术或统计在内的每一个分支中都变得越来越有用&#xff0c;以分析一些社会或非…

【C++容器】vector、map、hash_map、unordered_map四大容器的性能分析【2023.02.28】

摘要 vector是标准容器对数组的封装&#xff0c;是一段连续的线性的内存。map底层是二叉排序树。hash_map是C11之前的无序map&#xff0c;unordered_map底层是hash表&#xff0c;涉及桶算法。现对各个容器的查询与”插入“性能做对比分析&#xff0c;方便后期选择。 测试方案…

QT-自定义滑动式日期选择

QT-自定义滑动式日期选择前言一、效果演示二、注意说明二、关键程序1.SliderDateTime.cpp2.Slider.cpp四、程序链接前言 1、使用鼠标滑动的方式选择指定的日期时间&#xff0c;并且获取当前选中的时间&#xff0c;整体样式看来十分舒服&#xff0c;更加适用触摸屏的方式。 2、…

Python进阶-----面向对象1.0(对象和类的介绍、定义)

目录 前言&#xff1a; 面向过程和面向对象 类和对象 Python中类的定义 &#xff08;1&#xff09;类的定义形式 &#xff08;2&#xff09;深层剖析类对象 前言&#xff1a; 感谢各位的一路陪伴&#xff0c;我学习Python也有一个月了&#xff0c;在这一个月里我收获满满…