MySQL中的sql优化
目标:
掌握SQL调优的原则
掌握SQL调优的基本逻辑
掌握优秀SQL的编写方案
掌握何为慢SQL以及检测方案
SQL优化原则
1、减少数据量(表中数据太多可以分表,例如超过500万数据 双11一个小时一张订单表)
2、减少数据访问量(将全表扫描可以调整为基于索引去查询)
3、减少数据计算操作(将数据库中的计算拿到程序内存中计算)
SQL优化的基本逻辑
1、良好的SQL编码习惯(熟悉SQL编码规范、例如避免使用“select * “)
2、优秀SQL的编写逻辑(例如关联时遵循小表驱动大表)
3、定位需要优化的慢SQL语句(耗时多少时间的SQL是慢SQL)
4、调整优化策略并进行测试(SQL结构上的调整、索引应用)
5、按业务进行分库分表。(分表可以在应用逻辑中减少单表数据量)
优秀的SQL编写方案
1、查询时尽量避免使用 select *。
这样可以减少数据扫描以及网络开销(很多查询不需要查询所有列)
要尽量使用覆盖索引(索引中已经包含你需要的数据)、减少回表查询
如何查询会基于salary找到雇员id,然后基于雇员id再去查hire_date.(回表)
create index index_salary on employees(salary);
select employee_id,salary,hire_date
from employees
where salary>15000
优化方案:
create index index_salary on employees(salary,hire_date);
select employee_id,salary,hire_date
from employees
where salary>15000
2、尽量避免在where子句中使用 or 作为查询条件
or可能会使索引失效,进而执行全表扫描
全表查询的效率相对基于索引查询的效率会比较低
例如:
create index index_salary on employees(salary);
select first_name,hire_date,salary
from employees
where job_id='AD_VP' or salary>15000
优化方案:将or操作换成union操作
select first_name,hire_date,salary
from employees
where job_id='AD_VP'
union all(union 是将查询结果去重)
select first_name,hire_date,salary
from employees
where salary>15000
3、where条件中尽量不要出现null值的比较
条件中包含和null值的比较时可能会不走索引,当然这也跟SQL优化器有关,优化器有时会因为数据量的多少,对是否走索引进行评估,假如它认为不走索引效率可能会更 高,可能就不走索引了。
select first_name,salary,commission_pct
from employees
where commission_pct is null
4、避免在查询中存在隐式转换
create table tb_order
(
id int primary key,
user_id varchar(50) not null,
index index_user_id (user_id)
)
select * from tb_order where user_id=1; 这里存在隐式转换,有可能不走索引
select * from tb_order where user_id='2'; 推荐
5、避免在where子句中使用 != 或 <> 操作符
实际应用中这个查询是否走索引还与数据量有关
Select first_name
from employees
where job_id!='AD'
6、使用like查询条件时应尽量避免前缀使用‘%’
Select first_name,salary
from employees
where first_name like ‘%A%’
7、执行查询时尽量采用最左匹配原则
create index ‘index_hire_date_salary_pct’ on employees (hire_date,salary,commission_pct);
这里相当于创建了(hire_date),(hire_date,salary),(hire_date,salary,commission_pct)三个索引
假如我们执行如下查询可能就不走索引
select *
from employees
where salary>15000
假如我们这样执行查询,可能会走索引
select *
from employees
where hire_date >’2000-01-01’ and salary > 15000
8、避免在查询条件中使用一些内置的SQL函数
select *
from employees
where year(hire_date)=‘2000’
注意:在MySQL8.0中也可以基于函数创建索引了
9、假如in表达式后面的数据太多(一般不建议超过200),尽量避免使用in作为查询条件
10、当有多个查询条件、分组条件、排序条件时,尽量使用联合索引
11、表连接时优先使用内连接(inner join),使用小表驱动大表
12、进行表关联的字段尽量使用相同的编码(不能一个字段utf-8,一个字段utf8mb4)
13、表设计时字段类型能用简单类型不用复杂数据类型
14、清空表中数据可优先使用truncate
15、插入多条数据时考虑使用批量插入
慢sql查询分析
1、如何定位慢sql?
优化SQL的前提是能定位到慢SQL,例如查看慢SQL查询日志,确定已经执行完的慢查询
2、如何基于慢SQL日志查询慢SQL?
使用慢查询日志一般分为四步:
1、开启慢查询日志(一般默认是关闭状态) set global slow_query_log=ON
2、设置慢查询阈值(响应速度是多长时间被定义为慢SQL)set long_query_time=1
3、确定慢查询日志的路径(日志文件在哪里)show variables like ‘datadir’
4、确定慢查询日志的文件名(具体日志文件是哪一个),然后对文件内容进行分析 show global variables like ‘slow_query_log_file’
执行计划(Explain)
1、执行计划是什么?
执行计划是MySQL优化器对SQL进行默认调优的,给出的一个执行方案,这个方案我们可以通过explain这个指令进行查询。例如,对select语句进行分析,并输出select执行时的详细信息,开发人员可以基于这些信息进行有针对性的优化。
2、分析执行计划的目的?
1、检查关联查询的执行顺序
2、查询操作的具体类型
3、哪些索引可能会命中以及实际命中的索引有哪些
4、每张表可能有多少条记录参与到了查询中
3、执行计划中相关字段的说明
1、id
select的序列号,有几个select就有几个id,id的顺序是按select出现的顺序增长的,即:id越大执行优先级越高,id相同则从上往下执行,id为null最后执行
2、select_type
SIMPLE:表示查询语句不包含子查询或union
PRIMARY:表示此查询最外层的查询
UNION RESULT:union的结果
DEPENDENT UNION:子查询中的UNION操作,UNION后的所有select都是DEPENDENT UNION
SUBQUERY:select子查询语句
DEPENDENT SUBQUERY:子查询中的第一个select,select子查询语句依赖外层查询
DERIVED:from子句后的相对比较复杂子查询(相当于一个临时表),当看到derivedN时,这里的N表示查询id
3、type表示查询数据的方式(重点)
ALL:表示全表扫描,性能最差(数据量小时无所谓)
Index:表示基于索引的全表扫描,先扫描索引再扫描全表数据
Range:表示使用索引范围查询。使用>、>=、<、<=、in等
Index_merge:表示查询中使用到了多个索引,然后进行了索引合并
Ref:表示使用非唯一索引进行单值查询
Eq_ref:一般情况下出现在多表join查询,表示前面表的每一个记录,都只能匹配后面表的一行结果
Const:表示使用主键或唯一索引做等值查询,常量查询(效率非常高)
Null:表示不用访问表,也没有引用,速度最快
4、Extra值的含义是什么?
Using where:表示查询需要通过where条件查询数据(可能没有用到索引,也可能一部分用到了索引)
Using index:表示查询需要通过索引,索引就可以满足所需数据(不需要再回表查询,这里出现了索引覆盖)
Using filesort:表示查询出来的结果需要额外排序,数据量小在内存,大的话在磁盘,因此有Using filesort建议优化
Using temprorary:查询使用到了临时表,一般出现于去重、分组等操作(这里一般也需要优化)
Using index condition:表示查询的记录,在索引中没有完全覆盖(可能要基于where或二级索引对应的主键再次查询-回表查询)
MySQL中的sql优化的更多相关文章
- [转]Mysql中的SQL优化与执行计划
From : http://religiose.iteye.com/blog/1685537 一,如何判断SQL的执行效率? 通过explain 关键字分析效率低的SQL执行计划. 比如: expla ...
- MySQL中的SQL的常见优化策略
MySQL中的SQL的常见优化策略 MySQL中的索引优化 MySQL中的索引简介 1 避免全表扫描对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索 ...
- Mysql中的sql是如何执行的 --- 极客时间学习笔记
MySQL中的SQL是如何执行的 MySQL是典型的C/S架构,也就是Client/Server架构,服务器端程序使用的mysqld.整体的MySQL流程如下图所示: MySQL是有三层组成: 连接层 ...
- MySQL中的索引优化
MySQL中的SQL的常见优化策略 MySQL中的索引优化 MySQL中的索引简介 过多的使用索引将会造成滥用.因此索引也会有它的缺点.虽然索引大大提高了查询速度,同时却会降低更新表的速度,如对表进行 ...
- (6)MySQL进阶篇SQL优化(MyISAM表锁)
1.MySQL锁概述 锁是计算机协调多个进程或线程并发访问某一资源的机制.在数据库中,除传统的计算资源 (如 CPU.RAM.I/O 等)的抢占以外,数据也是一种供许多用户共享的资源.如何保证数 据并 ...
- MySQL中执行sql语句错误 Error Code: 1093. You can't specify target table 'car' for update in FROM clause
MySQL中执行sql语句错误 Error Code: 1093. You can't specify target table 'car' for update in FROM clause 201 ...
- 【原创】6. 在MYSQL++中实现SQL语法中的NULL
这次要说明的是在MYSQL++中为了实现SQL中的NULL而做出的一系列的举措.我的感觉是Null<T, B>类型通常出现在SSQLS和template Query中比较多. 1. 什么是 ...
- MySQL中的SQL流程分析简述
分析MySQL中这条语句的整个流程 update table_a set c1=xx where c2=xxx 朋友考我的一个问题在此处列出个人见解 1 客户端连接进来首先进行权限验证 2 验证通过后 ...
- MySQL 学习四 SQL优化
MySQL逻辑架构: 第一层:客户端层,连接处理,授权认证,安全等功能. 第二层:核心层,查询解析,分析,优化,缓存,内置函数(时间,数学,加密),存储过程,触发器,视图 第三层:存储引擎.负 ...
- 基于mysql数据库 关于sql优化的一些问题
mysql数据库有一个explain关键词,可以对select语句进行分析并且输出详细的select执行过程的详细信息. 对sql explain后输出几个字段: id:SELECT查询的标识符,每个 ...
随机推荐
- Vulhub 漏洞学习之:Django
Vulhub 漏洞学习之:Django 目录 Vulhub 漏洞学习之:Django 1 Django debug page XSS漏洞(CVE-2017-12794) 1.1 漏洞利用过程 2 Dj ...
- 2023.2.26【模板】扩展Lucas定理
2023.2.26[模板]扩展Lucas定理 题目概述 求\(\binom {n}{m} mod\) \(p\) 的值,不保证\(p\)为质数 算法流程 (扩展和普通算法毫无关系) 由于\(p\)不是 ...
- 基于C++的OpenGL 06 之摄像机
1. 引言 本文基于C++语言,描述OpenGL的摄像机 前置知识可参考: 基于C++的OpenGL 05 之坐标系统 - 当时明月在曾照彩云归 - 博客园 (cnblogs.com) 笔者这里不过多 ...
- LeetCode算法训练-回溯 491.递增子序列 46.全排列 47.全排列 II
欢迎关注个人公众号:爱喝可可牛奶 LeetCode算法训练-回溯 491.递增子序列 46.全排列 47.全排列 II LeetCode 491. 递增子序列 分析 找出并返回所有数组中不同的递增子序 ...
- LeetCode-539 最小时间差
来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/minimum-time-difference 题目描述 给定一个 24 小时制(小时:分钟 &q ...
- No.2.1
字体图标( 目的:使用字体图标技巧实现网页中简洁的图标效果) 字体图标展示的是图标,本质是字体,处理简单的.颜色单一的图片 优点:灵活性:灵活的修改样式,例如:尺寸,颜色等 轻量级:体积小,渲染快,降 ...
- Hsm状态机init()和dispatch()流程
(LCA)共同祖先状态:首先找到s(原状态)能处理t(目标状态)的超状态,然后找到t(目标状态)到上一步超状态的退出路径p[]并保存,最后沿着退出路径进入t目标状态. QHsm_dispatch_(Q ...
- ifconfig查询的时候,只有lo网卡,没有ens33网卡
问题ifconfig查询的时候,只有lo网卡,但是ifconfig -a查询的时候却有ens33网卡ls /etc/syconfig/network-scripts/查找所有网卡配置信息文件的时候,没 ...
- RestTemplate 远程服务调用
* 使用 Eureka 和 Nacos 为注册中心时也能使用这种方式调用 一.远程调用类 bean 配置注入 和 配置负载均衡 注意,必须在可配置类中注入 bean,例如 SpringBoot 启动 ...
- jenkins配置自动化
1.自定义jenkins自定义工作空间 --从SVN获取的项目会更新到对应空间 2.安装svn插件,填写项目地址 3.构建定时触发器,每天23点执行 4.执行调用用例脚本,解决测试报告样式展示问题 5 ...