SQL语句慢查询的缘由有多种,如:
1)数据方面:
须要查询的表数据量太大致使性能降低;
是否向数据库请求了不须要的数据行或数据列;
MySQL是否在扫描额外的记录mysql
2)SQL语句太过于冗余面试
3)等sql
下面咱们列出一下分析SQL查询慢的一些方法:数据库
一、记录慢查询日志缓存
分析查询日志,不要直接打开慢查询日志进行分析,这样比较浪费时间和精力,可使用pt-query-digest工具进行分析。服务器
二、使用show profile
使用步骤:架构
1)开启,服务器上执行的全部语句会检测消耗的时间,存到临时表中 set profiling = 1; 2)进行须要分析的SQL查询 ... 3)show profiles 4)show profile for query 临时表id
如:工具
mysql> set profiling = 1; Query OK, 0 rows affected (0.00 sec) mysql> show profiles; Empty set (0.00 sec) mysql> select * from a; +------+--------+ | id | name | +------+--------+ | 1 | nosee | | 2 | chan | | 3 | cheese | | 4 | xyz | +------+--------+ 4 rows in set (0.00 sec) mysql> show profiles; +----------+------------+-----------------+ | Query_ID | Duration | Query | +----------+------------+-----------------+ | 1 | 0.00054875 | select * from a | +----------+------------+-----------------+ 1 row in set (0.00 sec) mysql> show profile for query 1; +----------------------+----------+ | Status | Duration | +----------------------+----------+ | starting | 0.000063 | | checking permissions | 0.000013 | | Opening tables | 0.000050 | | System lock | 0.000018 | | init | 0.000023 | | optimizing | 0.000007 | | statistics | 0.000018 | | preparing | 0.000010 | | executing | 0.000004 | | Sending data | 0.000104 | | end | 0.000006 | | query end | 0.000004 | | closing tables | 0.000008 | | freeing items | 0.000196 | | logging slow query | 0.000022 | | cleaning up | 0.000006 | +----------------------+----------+ 16 rows in set (0.00 sec)
三、使用show status性能
show status会返回一些计数器,show global status 查看服务器级别的全部计数。有时根据这些计数,能够猜想出哪些操做代价较高或消耗时间多。学习
四、使用explain
explain命令用于分析单条SQL语句,是查看优化器如何决定执行查询的主要方法。
如:
mysql> explain select id from a where id =3\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: a type: ref possible_keys: id key: id key_len: 5 ref: const rows: 1 Extra: Using where; Using index 1 row in set (0.00 sec)
关于EXPLAIN更详细的内容请查看下一篇文章。
当但愿MySQL可以以更高的性能运行查询时,最好的办法就是弄清楚MySQL是如何优化和执行查询的。
当咱们向MySQL发送一个请求时,MySQL到底作了些什么,下面咱们经过一个简单的图解来进行分析:
1)客户端发送一条查询给服务器。
2)服务器先检查查询缓存,若是命中了缓存,则马上返回存储在缓存中的结果,不然进入下一阶段。
3)服务器进行SQL解析、预处理,再由优化器生成对应的执行计划。
4)MySQL根据优化器生成的执行计划,调用存储引擎的API来执行查询。
5)将结果返回给客户端。
上面的每一步都比想象的要复杂,这里将不深刻讨论。
一、定位问题
访问数据太多致使查询性能降低。
肯定应用程序是否在检索大量超过须要的数据,多是太多行或列。确认MySQL服务器是否在分析大量没必要要的数据行。
二、避免使用以下SQL语句
1)查询不须要的数据,使用limit解决
2)多表关联返回所有列,指定如A.id, A.name, B.age
3)老是取出所有列,SELECT *
会让优化器没法完成索引覆盖扫描的优化
4)重复查询相同的数据,能够缓存数据,下次直接读取缓存
三、是否在扫描额外的记录
使用explain来进行分析,若是发现查询须要扫描大量的数据但只返回少数的行,能够经过以下技巧去优化:
1)使用索引覆盖扫描,把全部用的列都放到索引中,这样存储引擎不须要回表获取对应行就能够返回结果
2)改变数据库和表的结构,修改数据表范式
3)重写SQL语句,让优化器能够以更优的方式执行查询
MySQL内部每秒能扫描内存中上百万行数据,相比之下,响应数据给客户端就要慢得多。使用尽量少的查询是最好的,但有时将一个大的查询分解为多个小的查询也是颇有必要的。
一、切分查询
将一个大的查询分为多个小的相同的查询。如一次性删除1000万的数据,要比一次删除1万暂停一会的方案更加损耗服务器开销。
二、分解关联查询
1)能够将一条关联语句分解成多条SQL来执行
2)执行单个查询能够减小锁的竞争
3)在应用层作关联能够更容易对数据库进行拆分
一、优化count()查询
1)count(*)中的*会忽略全部的列,直接统计全部列数,所以不要使用count(列名)。MyISAM中,没有任何WHERE条件的count(*)很是快。
2)可使用explain查询近似值,用近似值替代count(*)
3)增长汇总表
4)使用缓存
二、优化关联查询
1)肯定ON或USING子句的列上有索引
2)确保GROUP BY和ORDER BY中只有一个表中的列,这样MySQL才有可能使用索引
三、优化子查询
尽量使用关联查询来替代
四、优化GROUP BY和DISTINCY
1)这两种查询都可使用索引来优化,是最有效的优化方法
2)关联查询中,使用标识列进行分组的效率会更高
3)若是不须要ORDER BY,进行GROUP BY时使用ORDER BY NULL,MySQL不会进行文件排序
4)WITH ROLLUP超级聚合,能够挪到应用程序处理
五、优化LIMIT分页
LIMIT偏移量大的时候,查询效率较低。能够记录上次查询的最大ID,下次查询时直接根据该ID来查询。
六、优化UNION查询
UNION ALL的效率高于UNION。
一、请简述项目中优化SQL语句执行效率的方法,从哪些方面,SQL语句性能如何分析?
考官考点:
1)查找分析查询速度慢的缘由
2)优化查询过程当中的数据访问
3)优化长难的查询语句
4)优化特定类型的查询语句
对于此类问题,先说明如何定位低效率SQL语句,而后根据SQL语句可能低效的缘由作排查,先从索引着手,若是索引没问题,考虑以上几个方面:数据访问的问题、长难查询句的问题、仍是一些特定类型优化的问题,逐步排除。
以为不错请点赞支持,欢迎留言或进个人我的群855801563领取【架构资料专题目合集90期】、【BATJTMD大厂JAVA面试真题1000+】,本群专用于学习交流技术、分享面试机会,拒绝广告,我也会在群内不按期答题、探讨