MySQL 三万字精华总结 + 面试100 问,吊打面试官绰绰有余(收藏系列) (18)

注:log-slow-queries 参数为慢查询日志存放的位置,一般这个目录要有 MySQL 的运行帐号的可写权限,一般都将这个目录设置为 MySQL 的数据存放目录;long_query_time=2 中的 2 表示查询超过两秒才记录;在my.cnf或者 my.ini 中添加 log-queries-not-using-indexes 参数,表示记录下没有使用索引的查询。

可以用 select sleep(4) 验证是否成功开启。

在生产环境中,如果手工分析日志,查找、分析SQL,还是比较费劲的,所以MySQL提供了日志分析工具mysqldumpslow

通过 mysqldumpslow --help 查看操作帮助信息

得到返回记录集最多的10个SQL

mysqldumpslow -s r -t 10 /var/lib/mysql/hostname-slow.log

得到访问次数最多的10个SQL

mysqldumpslow -s c -t 10 /var/lib/mysql/hostname-slow.log

得到按照时间排序的前10条里面含有左连接的查询语句

mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/hostname-slow.log

也可以和管道配合使用

mysqldumpslow -s r -t 10 /var/lib/mysql/hostname-slow.log | more

也可使用 pt-query-digest 分析 RDS MySQL 慢查询日志

Show Profile 分析查询

通过慢日志查询可以知道哪些 SQL 语句执行效率低下,通过 explain 我们可以得知 SQL 语句的具体执行情况,索引使用等,还可以结合Show Profile命令查看执行状态。

Show Profile 是 MySQL 提供可以用来分析当前会话中语句执行的资源消耗情况。可以用于SQL的调优的测量

默认情况下,参数处于关闭状态,并保存最近15次的运行结果

分析步骤

是否支持,看看当前的mysql版本是否支持

mysql>Show variables like 'profiling'; --默认是关闭,使用前需要开启

开启功能,默认是关闭,使用前需要开启

mysql>set profiling=1;

运行SQL

查看结果

mysql> show profiles;
+----------+------------+---------------------------------+
| Query_ID | Duration | Query |
+----------+------------+---------------------------------+
| 1 | 0.00385450 | show variables like "profiling" |
| 2 | 0.00170050 | show variables like "profiling" |
| 3 | 0.00038025 | select * from t_base_user |
+----------+------------+---------------------------------+

诊断SQL,show profile cpu,block io for query id(上一步前面的问题SQL数字号码)

日常开发需要注意的结论

converting HEAP to MyISAM 查询结果太大,内存都不够用了往磁盘上搬了。

create tmp table 创建临时表,这个要注意

Copying to tmp table on disk 把内存临时表复制到磁盘

locked

查询中哪些情况不会使用索引?

性能优化 索引优化

全值匹配我最爱

最佳左前缀法则,比如建立了一个联合索引(a,b,c),那么其实我们可利用的索引就有(a), (a,b), (a,b,c)

不在索引列上做任何操作(计算、函数、(自动or手动)类型转换),会导致索引失效而转向全表扫描

存储引擎不能使用索引中范围条件右边的列

尽量使用覆盖索引(只访问索引的查询(索引列和查询列一致)),减少select

is null ,is not null 也无法使用索引

like "xxxx%" 是可以用到索引的,like "%xxxx" 则不行(like "%xxx%" 同理)。like以通配符开头('%abc...')索引失效会变成全表扫描的操作,

字符串不加单引号索引失效

少用or,用它来连接时会索引失效

<,<=,=,>,>=,BETWEEN,IN 可用到索引,<>,not in ,!= 则不行,会导致全表扫描

一般性建议

对于单键索引,尽量选择针对当前query过滤性更好的索引

在选择组合索引的时候,当前Query中过滤性最好的字段在索引字段顺序中,位置越靠前越好。

在选择组合索引的时候,尽量选择可以能够包含当前query中的where字句中更多字段的索引

尽可能通过分析统计信息和调整query的写法来达到选择合适索引的目的

少用Hint强制索引

查询优化

永远小标驱动大表(小的数据集驱动大的数据集)

slect * from A where id in (select id from B)`等价于 #等价于 select id from B select * from A where A.id=B.id

当 B 表的数据集必须小于 A 表的数据集时,用 in 优于 exists

select * from A where exists (select 1 from B where B.id=A.id) #等价于 select * from A select * from B where B.id = A.id`

当 A 表的数据集小于B表的数据集时,用 exists优于用 in

注意:A表与B表的ID字段应建立索引。

order by关键字优化

order by子句,尽量使用 Index 方式排序,避免使用 FileSort 方式排序

MySQL 支持两种方式的排序,FileSort 和 Index,Index效率高,它指 MySQL 扫描索引本身完成排序,FileSort 效率较低;

ORDER BY 满足两种情况,会使用Index方式排序;①ORDER BY语句使用索引最左前列 ②使用where子句与ORDER BY子句条件列组合满足索引最左前列

尽可能在索引列上完成排序操作,遵照索引建的最佳最前缀

如果不在索引列上,filesort 有两种算法,mysql就要启动双路排序和单路排序

双路排序:MySQL 4.1之前是使用双路排序,字面意思就是两次扫描磁盘,最终得到数据

单路排序:从磁盘读取查询需要的所有列,按照order by 列在 buffer对它们进行排序,然后扫描排序后的列表进行输出,效率高于双路排序

优化策略

增大sort_buffer_size参数的设置

增大max_lencth_for_sort_data参数的设置

GROUP BY关键字优化

group by实质是先排序后进行分组,遵照索引建的最佳左前缀

当无法使用索引列,增大 max_length_for_sort_data 参数的设置,增大sort_buffer_size参数的设置

where高于having,能写在where限定的条件就不要去having限定了

数据类型优化

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpwygy.html