BATJ解决千万级别数据之MySQL 的 SQL 优化大总结
引用
在数据库运维过程中,优化 SQL 是 DBA 团队的日常任务。例行 SQL 优化,不仅可以提高程序性能,还能减低线上故障的概率。
目前常用的 SQL 优化方式包括但不限于:业务层优化、SQL 逻辑优化、索引优化等。其中索引优化通常通过调整索引或新增索引从而达到 SQL 优化的目的。索引优化往往可以在短时间内产生非常巨大的效果。
--- 来自美团技术团队
SQL 优化是一个复杂的问题,不同版本和种类的数据库、不同数据级的数据需要选择不同的优化策略。
说明:我这里简单总结一下 SQL 优化,很多的大佬写过这方面的细节和用法,甚至还有相关的案例。我只是作为一个阶段性的总结,肯定是不全面的。如有错误和不当之处,欢迎批评指正,不胜感激。
从日常开发写 SQL 的角度看,需要遵循一些规则,但是这些规则只能解决部分问题。因为随着开发和数据量的增长,SQL 还是会变慢,这个时候需要一些针对性的措施,比如针对性地添加索引,通过命令或者工具分析变慢的 SQL 等等。
说说 SQL 优化的其中两个大的原则(肯定还有别的):
原则一:尽量避免全表扫描。
原则二:通过索引优化。
这两个涉及的点比较多,他们之间也是有联系的,下面详细说说。
1、避免全表扫描
为啥要避免全表扫描呢?因为全表扫描耗费更多的时间。
那么从哪些方法避免全表扫描呢?
对 where 和 order by 涉及的列建立索引可以提高访问速度。但是要注意,并不是你建立了索引,索引就一定会生效。如果没有生效查询时还是全表扫描,速度还是得不到提升。那如何判断索引没有生效呢?可以借助 explain + SQL 语句的结果判断。大佬写的MySQL EXPLAIN 命令: 查看查询执行计划中总结了用法。简单的说,使用该命令分析的结果中很多字段,其中type 描述了查询的方式,如果 type 的结果是ALL,那么索引肯定没起作用。下面总结一下如何避免索引失效。
1.避免在 where 子句中对字段进行 null 判断
select id from user where name is null
2.避免在 where 子句使用 != 或者 <>
3.避免在 where 子句中对表达式进行操作
select id from user where age/2 = 20
4.避免在 where 子句中对字段进行函数操作
5.避免在 like 查询中将 %放在开头
select id from user where username like '%wh'
> 2、索引优化
适当地添加索引可以提高 SQL 的速度,但也有些注意点。
1.使用联合索引时,注意索引列的顺序,一般遵循最左匹配原则
比如一个索引:
KEY `idx_userid_age` (`userId`, `age`) USING BTREE
符合最左匹配原则的写法是把userid放在前面
select userid, name from user where userid = 1001 and age = 10
当我们创建的这个联合索引,就相当于创建了(userid)和(userid, age)两个索引。联合索引不满足最左原则,一般会失效,但是这个还跟 MySQL 优化器有关系。
2.在适当的时候,使用覆盖索引
通常在使用索引检索数据之后,需要访问磁盘上数据表文件读取所需要的列,这种操作成为“回表”。
若索引中包含查询的所有列,则不需要回表操作,直接从索引文件中读取数据即可,这种索引成为“覆盖索引”。
在查询时尽量减少select *,只查询需要的行,条件允许时尽量建立覆盖索引。
3.删除冗余索引
索引并不是越多越好,冗余的索引会影响性能。
比如,索引(A, B)相当于创建了索引(A)和索引(A, B)。
4.注意索引的数量
索引不是越多越好,一般不要超过 5 个。索引虽然提高了查询效率,但是也会降低插入和更新的效率。插入或更新可能会重建索引,索引建立索引也需要慎重考虑。
5.索引不适合建立在有大量重复的字段上,如性别这类字段
> 其他
其他原则包括但不限于:
- 查询 SQL 尽量不要使用 select *,而是 select 某字段。
- 连表查询的时候尽量将数据量少的表驱动数据多的表。
- 如果插入的数据较多时,考虑批量插入。
- 原则上不要有超过 5 张以上的表连接
阿里巴巴开发手册中规定超过三个表禁止 join的,但是这些规范的适用性还是要考虑环境。当连表数量较少时,连表路径算法选择的是动态规划算法;但是连表太多的情况下,路径算法可能退化成贪心算法,连表的方案可能不是最优的的。
这种情况下,如何写 SQL 呢?答案是通过可以通过冗余实现,细节就不展开了。
通过工具分析 SQL
说说几个用到的 SQL 分析工具
** 1.MySQL 自带的慢查询日志**
MySQL 的慢查询日志是 MySQL 提供的一种日志,记录,用于记录在 MySQL 中响应时间超过设定的阈值的语句。在 MySQL 的配置文件 my.ini中开启后,支持将慢查询日志写入文件或者数据库。通过explain关键词模拟优化器执行 SQL,分析慢查询 SQL。
分析相关语句使用了哪些表、连接的类型、扫描的行数、使用的索引等。
2.日志分析工具 MySQLdumpslow
在生产环境中,手工分析日志、查找 SQL 比较费时间。MySQL 提供的 MySQLdumpslow 工具可以得到一些 SQL 访问的统计数据,比如访问次数最多的 10 条 SQL 等。\
3.第三方工具:美团技术团队的 SQLAdvisor
由美团技术团队维护的一个开源的分析 SQL,给出索引优化建议的工具。
只是大概做了个总结,细节都没有展开,有兴趣的同学自行学习吧。
本文由博客一文多发平台 OpenWrite 发布!
BATJ解决千万级别数据之MySQL 的 SQL 优化大总结的更多相关文章
- 千万级别数据量mysql优化策略
表结构优化 1. 使用独立表空间 独立表空间指的是innodb表的一种数据结构 独占表空间: 每一个表都将会生成以独立的文件方式来进行存储,每一个表都有一个.frm表描述文件,还有一个.ibd文件 ...
- mysql数据库千万级别数据的查询优化和分页测试
原文地址:原创 mysql数据库千万级别数据的查询优化和分页测试作者:于堡舰 本文为本人最近利用几个小时才分析总结出的原创文章,希望大家转载,但是要注明出处 http://blog.sina.com. ...
- 基于MySQL 的 SQL 优化总结
文章首发于我的个人博客,欢迎访问.https://blog.itzhouq.cn/mysql1 基于MySQL 的 SQL 优化总结 在数据库运维过程中,优化 SQL 是 DBA 团队的日常任务.例行 ...
- mysql的sql优化案例
前言 mysql的sql优化器比较弱,选择执行计划貌似很随机. 案例 一.表结构说明mysql> show create table table_order\G***************** ...
- MySQL之SQL优化详解(二)
目录 MySQL之SQL优化详解(二) 1. SQL的执行顺序 1.1 手写顺序 1.2 机读顺序 2. 七种join 3. 索引 3.1 索引初探 3.2 索引分类 3.3 建与不建 4. 性能分析 ...
- 我的mysql数据库sql优化原则
原文 我的mysql数据库sql优化原则 一.前提 这里的原则 只是针对mysql数据库,其他的数据库 某些是殊途同归,某些还是存在差异.我总结的也是mysql普遍的规则,对于某些特殊情况得特殊对待. ...
- LOAD DATA INFILE读取CSV中一千万条数据至mysql
作业要求 构建一个关系模式和课本中的关系movies(title,year,length,movietype,studioname,producerC)一样的关系,名称自定,在这个关系中插入1000万 ...
- 千万级大数据的Mysql数据库SQL语句优化
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- MySQL 慢 SQL & 优化方案
1. 慢 SQL 的危害 2. 数据库架构 & SQL 执行过程 3. 存储引擎和索引的那些事儿 3.1 存储引擎 3.2 索引 4. 慢 SQL 解决之道 4.1 优化分析流程 4.2 执行 ...
随机推荐
- 使用spring boot创建fat jar APP
文章目录 介绍 build和run fat jar和 fat war 更多配置 介绍 在很久很很久以前,我们部署web程序的方式是怎么样的呢?配置好服务器,将自己写的应用程序打包成war包,扔进服务器 ...
- Vue Cli 3 搭建单页应用项目刷新 404 问题 解决方案(以Apache为例)
vue 项目 版本 Vue Cli 3.3 官方文档 https://router.vuejs.org/zh/guide/essentials/history-mode.html 因为本项目部署在 A ...
- JavaScript 后台获取数据 - HTTP203 Advent(中文字幕)
如果关注过 Google 相关的开发技术,对 HTTP203 这个栏目应该不陌生. 这是 HTTP203 圣诞节的特别版! Jake(@jaffathecake)和 Surma(@DasSurma)有 ...
- Leo2DNT(雷傲论坛转DiscuzNT)1.0转换程序发布
数据转换程序 雷傲论坛(Leobbs4.x) -> Discuz!NT V1.0 本转换程序基于Leobbs4.x设计 声明: 1.本程序只对数据作转换,不会对原来的雷傲论坛(数据 ...
- Geomesa-Hbase集群部署
本文记录一下Geomesa-Hbase集群部署,在单机部署的基础上 https://www.cnblogs.com/help-silence/p/12817447.html 1.搭建集群 https: ...
- 阿里云服务器连接AWS-S3
1.找到一个路径下载 aws-cli (使用离线包安装) wget -P /usr/local/software https://s3.amazonaws.com/aws-cli/awscli-bu ...
- 支付宝小程序serverless---获取用户信息(头像)并保存到云数据库
支付宝小程序serverless---获取用户信息(头像)并保存到云数据库 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 我又 ...
- S - Making the Grade POJ - 3666 结论 将严格递减转化成非严格的
S - Making the Grade POJ - 3666 这个题目要求把一个给定的序列变成递增或者递减序列的最小代价. 这个是一个dp,对于这个dp的定义我觉得不是很好想,如果第一次碰到的话. ...
- 文件相关命令(find,tree,tar)文件属性信息 date
6.13day11 文件相关命令(find,tree,tar)文件属性信息date 1 文件相关命令 1.1 find命令 查找文件用f find /root -type f -name " ...
- Java中的内存
目录 栈(Stack):存放的都是方法中的局部变量.方法的运行一定要在栈当中. 堆(Heap):凡是new出来的东西,都在堆内存当中 方法区(Method Area):存储.class相关信息,包含方 ...