博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Mysql基础课十:sql 优化
阅读量:3735 次
发布时间:2019-05-22

本文共 2783 字,大约阅读时间需要 9 分钟。

SQL 优化

  1. 语句 show status [session/global] 可以显示数据库的统计信息,如 select 操作执行次数,commit 次数,rollback 次数等,通过参数 --log-slow-queries[=file_name] 来指定慢查询日志存放,参数 -… 指定慢查询阈值;

  2. explain 分析 sql 语句,type 字段,有 all 表示全表扫描,index 表示索引查找,range 表示索引范围查找,ref 表示非唯一索引,eq_ref 表示唯一索引,const / system 表示常量,null 表示

  3. explain 结果的 key,表示实际使用的所有,rows 表示扫描的行数

  4. 语句 explain extended sql,显示 sql 在执行中有哪些优化;explain partitions sql,显示执行访问的分区;trace,用来跟踪 sql;

set optimizer_trace="enabled=on",end_markers_in_json=on;	set optimizer_trace_max_mem_size=1000000;	sql	select * from information_schema.optimizer_trace;
  1. explain 结果的extra,如果是 using where,表示需要回表,like 子句,如果以 % 开头,是无法使用索引,出现隐式类型转换也是不会使用到索引; where 子句中如果出现 or,且又一个条件是非索引,就会使用全表扫描;
// last_name 为字符型,这种情况下,就不会用到该索引	select * from actor where last_name = 1;
  1. 常用优化手段,定期分析表,检查表和优化表,业务上尽量减少 order by,使用索引有序的数据,适当加大max_length_for_sort_data的值,使排序在内存中完成,而不使用临时表; group by:默认会按其指定字段排序,可以添加order by null 禁止排序来改善性能;尽量用 join 代替 子查询;or 组成并集条件时,要求每个条件都是索引字段;
//使sql能生成正确执行计划	analyze table table_name; 	//检查是否有错误 	check table table_name;   	//优化表,可以整理碎片	optimize table table_name;

Sql语句执行慢

  1. 查询语句长时间不返回,可能是表锁住了,可以通过命令 show processlist 来分析下当前语句处于什么状态,如果是 waiting for table metadata lock,就说明其他 session 占有了 MDL 写锁没有释放,通过 select blocking_pid from sys.schema_table_lock_waits 可以找到阻塞的 process_id,kill 断开即可;

  2. 如果通过 show processlist 返回的是 wait for table flush,表示 flush 操作阻塞了 select 查询语句,通常 flush 操作很快,所以要查看什么操作 阻塞了 flush 操作,然后 kill 断开相应的操作;

  3. 如果返回的是 等行锁,就需要通过 select * from t sys.innodb_lock_waits where locked_table=’test.t’\G 来获取占用锁的线程,执行 kill 操作;

数据库连接不足

  1. 如果业务中大量使用短连接,当机器负载高,出现请求时间过长,导致连接数大量增加,超过 max-connections 的限制,Mysql 因此拒绝了新的连接,就需要考虑如何恢复业务;

  2. 首先考虑处理掉,占着连接但不工作的线程,并且优先断开非事务的空闲太久的连接,如果还不够,再断开事务内空闲太久的连接,

  3. 服务端断开连接,使用命令 kill connection + id ,如果客户端处于 sleep 状态时,它的连接被服务端主动断开后,客户端并不会马上知道,直到客户端在发起下一个请求的时候,才会收到这样的报错;

  4. 命令 show processlist 查看连接状态,information_schema 库的 innodb_trx 表 查看事务具体状态;

  5. 第二种方案是,减少连接过程的消耗,一种可能的做法是,让数据库跳过权限验证阶段,不太推荐;

慢查询

  1. 慢查询通常是:索引没有设计好,SQL 语句没写好,或者 MySQL 选错了索引;

  2. 索引没有设计好,可以通过,紧急创建索引,MySQL 5.6 版本以后,创建索引已经支持 Online DDL;

  3. SQL 语句,可以通过改写处理,MySQL 5.7 提供了 query_rewrite 功能,可以把输入的一种语句改写成另外一种模式,而不必紧急修改应用代码;

// 改写 id + 1 = ? 为 id = ? - 1	mysql> insert into query_rewrite.rewrite_rules(pattern, replacement, pattern_database) values ("select * from t where id + 1 = ?", "select * from t where id = ? - 1", "db1");	call query_rewrite.flush_rewrite_rules();
  1. 选错索引,同样地,使用查询重写功能,给原来的语句加上 force index,避免修改应用代码,需要紧急上线;

  2. 预先发现问题,上线前,在测试环境,把慢查询日志(slow log)打开,并且把 long_query_time 设置成 0,确保每个语句都会被记录入慢查询日志;然后在测试表里插入模拟线上的数据,做一遍回归测试;观察慢查询日志里每类语句的输出,特别留意 Rows_examined 字段是否与预期一致。

你做业务开发的话,要知道,连接异常断开是常有的事,你的代码里要有正确地重连并重试的机制。

QPS 突增问题

  1. 由于业务突然出现高峰,或者应用程序 bug,导致某个语句的 QPS 突然暴涨,最理想的情况需要做服务降级,可能要下掉该功能;

  2. 从数据库角度,下掉某个功能,可以在数据库白名单将应用部署地址去掉,如果是单独的用户,可以删除该用户,最后一种方法是将引起 QPS 暴涨的语句,在线改写为 select 1 返回;

tips

  1. myISAM对表总数有缓存,而innodb没有;

  2. sql 中字符串,使用单引号;

转载地址:http://ssfin.baihongyu.com/

你可能感兴趣的文章
西南科技大学Power OJ:实验六 F: 课本第七章-8 数字间加空格 在主函数中输入一个4位数字,写一个子函数,要求输出这4个数字字符,但每两个数字间空一个空格。
查看>>
Anaconda主页(Home)中没有VS Code的解决办法
查看>>
8086中,一个存储单元的物理地址是固定的,但是可以有多个逻辑地址吗 / 一个物理地址可以有多个逻辑地址与之对应吗
查看>>
西南科技大学Power OJ:实验六 G: 课本第七章-10 最长单词 在主函数中输入一行字符串(该行字符串中有空格),写一个子函数,将此字符串中最长的单词输出。如果同时有多个最长的单词,输出第
查看>>
西南科技大学Power OJ:实验六 H: 课本第七章-11 冒泡排序 在主函数中输入一串长度小于100的字符串。调用一个子函数,用“起泡法”对输入的字符串按由小到大顺序排列,最后在主函数中输出。
查看>>
在Anaconda下安装Pytorch的超详细步骤
查看>>
Anaconda的下载及安装——详细图文教程
查看>>
python安装好了但是发现在cmd键入python没有反应的解决方法
查看>>
cmd中输入 python 进入微软商店
查看>>
安装QQ的时候显示创建文件夹失败,无法正常安装,请尝试选择新的安装目录的解决办法
查看>>
笔记本因网络重置导致网络连接中WLAN消失而无法连接无线网络的解决办法
查看>>
数字图像处理——绘制灰度直方图(遍历每个像素点的方法)
查看>>
药品管理系统C语言实现 BME讲座记录
查看>>
J2EE的文件结构建立和细节和maven建立系统的标准结构 pom文件包作用 和各个建包
查看>>
基于J2EE架构的登录页面的验证和实现和验证码设置,servlet+JSP+JavaScript实现
查看>>
C3P0数据源的连接数据库配置的相关配置和Java类实现,JDBC 和使用UUID获取随机ID
查看>>
mysql数据库查出来显示乱码,不识别中文,响应到JSP页面中
查看>>
servlet取到传来所有参数信息map集合,然后数据封装到JavaBean对象中 和将string改为date类型
查看>>
dao层持久层运用QueryRunner+C3P0实现对数据库的所有操作 增删改查 特殊条件查询
查看>>
eclipse导入项目 maven
查看>>