MySQL--索引及优化查询
时间:2022-07-22
本文章向大家介绍MySQL--索引及优化查询,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
根据 MySQL索引原理及慢查询优化 整理
索引相关
索引的目的
索引的目的在于提高查询效率。
索引的原理
通过不断的缩小要查询的数据的范围来筛选出最终想要的结果,同时将随机的事件变成顺序事件。
数据库则复杂得多,不仅需要面对等值查询,还有范围插叙(<, >, between, in)、模糊查询(like)、并集查询(or)等等。 简单的搜索树难以满足复杂的应用场景。
磁盘的IO与预读
磁盘的IO是非常昂贵的操作。计算机操作系统做了一些优化,当一次IO时,不光读取当前磁盘地址的数据,而是把相邻的数据也都读取到内存缓冲区。每次IO读取的数据我们称之为一页(page)。一页一般为4kb或者8kb。
索引的数据结构
我们需要的数据结构:每次查找数据时,都要把磁盘IO次数控制在一个很小的数量级,最好是常数数量级。一个高度可控的多路搜索树是否能够满足需求呢?B+树应运而生。
详解B+树
B+树是一种树数据结构,通常用于数据库和操作系统的文件系统中。B+树的特点是能够保持数据稳定有序,其插入与修改拥有较稳定的对数时间复杂度。B+树元素自底向上插入,这与二叉树恰好相反。
真实数据存储于叶子节点,非叶子节点不存储真实数据,只存储指引搜索方向的数据项。
B+树的查找过程
内存查询时间非常短(相比于磁盘的IO)可以忽略不计。真实的情况是3层B+树,可以表示上百万的数据。如果上百万的数据查找只需要三次IO,性能提高将是巨大的。
B+树的性质
- 通过上面的分析,我们知道IO的次数取决于树的高度H,假设当前数据表的数据为N,每个磁盘块的数据项的数量是M,则有
H=log(M+1)N
。当数据量N一定的情况下,M越大,H越小;而M=磁盘块的大小/数据项的大小
,磁盘块的大小也就是一个数据页的大小,是固定的。如果数据项占用的空间越小,数据项就越多,树的高度就会越低。这就是为什么每个数据项,即索引字段要尽量小。这也是为什么B+树要求把真实数据存储到叶子节点而不是内层节点,一旦放到内层节点,磁盘块的数据项会大幅度下降,导致树增高。当数据项等于1时,将会退化成线性表。 - 当B+树的数据项是复合的数据结,比如(name, age, sex)时,B+树是按照从左到右的顺序来简历搜索树的。索引的最左匹配特性。
慢查询优化
建立索引的几大原则
- 最左前缀匹配原则。 MySQL会一直想有匹配直到遇到范围查询(<, >, between, like)就停止匹配。
- =和in可以乱序。MySQL查询优化器可以帮你优化成索引可以识别的形式。
- 尽量选择区分度高的列作为索引。区分度公式:
COUNT(DISTINCT col)/COUNT(*)
,表示字段的不重复比例,比例越大扫描的表就越少,唯一键的缺乏难度为1。根据使用场景的不同,这个值也很难确定,一般需要join的字段我们都要求是0.1以上。 - 索引列不能参与计算。保持列“干净”。
- 尽量的扩展索引,不要新建索引。
查询优化神器 -- explain命令
慢查询优化基本步骤
- 先运行看下是否真的很慢,注意设置
SQL_NO_CACHE
- wnere条件单表查,锁定最小返回记录表。这句话的意思是把查询语句的where都应用到表中返回的记录最小的表开始查起,单表每个字段分别查询,看哪个字段的区分度最高
-
explain
查看执行计划,是否与1预期一致(从锁定记录较少的表开始查询) -
order by limit
形式的sql语句,让排序的表优先查询 - 了解业务方使用场景
- 增加索引时,参照索引的几大原则
- 观察结果,不符合预期继续从0分析
写在后面的话
任何数据库层面的优化都抵不上应用系统的优化。
- crontab导致CPU异常的问题分析及处理(r3笔记第100天)
- 短信接口被恶意调用(二)肉搏战-阻止恶意请求
- 关于首屏时间采集自动化的解决方案
- javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites
- 一次数据库无法登陆的问题及排查 (r3笔记第99天)
- 用深度学习keras的cnn做图像识别分类,准确率达97%
- 短信发送接口被恶意访问的网络攻击事件(三)定位恶意IP的日志分析脚本
- job处理缓慢的性能问题排查与分析(r4笔记第18天)
- 京东商品评论情感分析:数据采集与词向量构造方法
- springboot开启access_log日志输出
- 完美的执行计划导致的性能问题(r4笔记第17天)
- 解决Docker容器时区及时间不同步的问题
- 移动端测试方案--sptt
- 服务端事件EventSource揭秘
- MySQL 教程
- MySQL 安装
- MySQL 管理与配置
- MySQL PHP 语法
- MySQL 连接
- MySQL 创建数据库
- MySQL 删除数据库
- MySQL 选择数据库
- MySQL 数据类型
- MySQL 创建数据表
- MySQL 删除数据表
- MySQL 插入数据
- MySQL 查询数据
- MySQL where 子句
- MySQL UPDATE 查询
- MySQL DELETE 语句
- MySQL LIKE 子句
- mysql order by
- Mysql Join的使用
- MySQL NULL 值处理
- MySQL 正则表达式
- MySQL 事务
- MySQL ALTER命令
- MySQL 索引
- MySQL 临时表
- MySQL 复制表
- 查看MySQL 元数据
- MySQL 序列 AUTO_INCREMENT
- MySQL 处理重复数据
- MySQL 及 SQL 注入
- MySQL 导出数据
- MySQL 导入数据
- MYSQL 函数大全
- MySQL Group By 实例讲解
- MySQL Max()函数实例讲解
- mysql count函数实例
- MYSQL UNION和UNION ALL实例
- MySQL IN 用法
- MySQL between and 实例讲解
- 急速 debug 实战二(浏览器 - 调试线上篇)
- via the 'serverTimezone' configuration property
- 急速 debug 实战一(浏览器-基础篇)
- MongoDB系列一: Replica Set 集群搭建实战
- 函数式编程看React Hooks(一)简单React Hooks实现
- 函数式编程看React Hooks(二)事件绑定副作用深度剖析
- Vue 开发必须知道的 36 个技巧【近1W字】
- 吃透 Vue 项目开发实践|16个方面深入前端工程化开发技巧《上》
- 【漫游Github】无编译/无服务器,实现浏览器的 CommonJS 模块化
- 《秋风日常第一期》白板协作工具 LeanBoard
- 《秋风日常第二期》一个快速找出待SEO图片的技巧
- 《模块化系列》snowpack,提高10倍打包速度。
- 《秋风日常第三期》11个前端开发者必备的网站
- 专为程序员定制的垃圾清理工具(Node Cli实现)
- CodePen vue SFC 、flutter 在线玩耍来袭