一般要进行SQL调优,那么就说有慢查询的SQL,系统或者server可以开启慢查询日志,尤其是线上系统,一般都会开启慢查询日志,如果有慢查询,可以通过日志来过滤。但是知道了有需要优化的SQL后,下面要做的就是如何进行调优
慢查询优化基本步骤
- 先运行看看是否真的很慢,注意设置SQL_NO_CACHE
- where条件单表查,锁定最小返回记录表。这句话的意思是把查询语句的where都应用到表中返回的记录数最小的表开始查起,单表每个字段分别查询,看哪个字段的区分度最高
- explain查看执行计划,是否与1预期一致(从锁定记录较少的表开始查询)
- order by limit 形式的sql语句让排序的表优先查
- 了解业务方使用场景
- 加索引时参照建索引的几大原则
- 观察结果,不符合预期继续从0分析
常用调优手段
执行计划explain
在日常工作中,我们有时会开慢查询去记录一些执行时间比较久的SQL语句,找出这些SQL语句并不意味着完事了,我们常常用到explain这个命令来查看一个这些SQL语句的执行计划,查看该SQL语句有没有使用上了索引,有没有做全表扫描,这都可以通过explain命令来查看。
所以我们深入了解MySQL的基于开销的优化器,还可以获得很多可能被优化器考虑到的访问策略的细节,以及当运行SQL语句时哪种策略预计会被优化器采用。
使用explain 只需要在原有select 基础上加上explain关键字就可以了,如下:
- mysql> explain select * from servers;
- +----+-------------+---------+------+---------------+------+---------+------+------+-------+
- | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
- +----+-------------+---------+------+---------------+------+---------+------+------+-------+
- | 1 | SIMPLE | servers | ALL | NULL | NULL | NULL | NULL | 1 | NULL |
- +----+-------------+---------+------+---------------+------+---------+------+------+-------+
- 1 row in set (0.03 sec)
简要解释下explain各个字段的含义
- id : 表示SQL执行的顺序的标识,SQL从大到小的执行
- select_type:表示查询中每个select子句的类型
- table:显示这一行的数据是关于哪张表的,有时不是真实的表名字
- type:表示MySQL在表中找到所需行的方式,又称“访问类型”。常用的类型有:ALL, index, range, ref, eq_ref, const, system, NULL(从左到右,性能从差到好)
- possible_keys:指出MySQL能使用哪个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不一定被查询使用
- Key:key列显示MySQL实际决定使用的键(索引),如果没有选择索引,键是NULL。
- key_len:表示索引中使用的字节数,可通过该列计算查询中使用的索引的长度(key_len显示的值为索引字段的最大可能长度,并非实际使用长度,即key_len是根据表定义计算而得,不是通过表内检索出的)
- ref:表示上述表的连接匹配条件,即哪些列或常量被用于查找索引列上的值
- rows:表示MySQL根据表统计信息及索引选用情况,估算的找到所需的记录所需要读取的行数,理论上行数越少,查询性能越好
- Extra:该列包含MySQL解决查询的详细信息
EXPLAIN的特性
- EXPLAIN不会告诉你关于触发器、存储过程的信息或用户自定义函数对查询的影响情况
- EXPLAIN不考虑各种Cache
- EXPLAIN不能显示MySQL在执行查询时所作的优化工作
- 部分统计信息是估算的,并非精确值
- EXPALIN只能解释SELECT操作,其他操作要重写为SELECT后查看执行计划。
实战演练
表结构和查询语句
假如有如下表结构
- circlemessage_idx_0 | CREATE TABLE `circlemessage_idx_0` (
- `circle_id` bigint(20) unsigned NOT NULL COMMENT '群组id',
- `from_id` bigint(20) unsigned NOT NULL COMMENT '发送用户id',
- `to_id` bigint(20) unsigned NOT NULL COMMENT '指定接收用户id',
- `msg_id` bigint(20) unsigned NOT NULL COMMENT '消息ID',
- `type` tinyint(3) unsigned NOT NULL DEFAULT '0' COMMENT '消息类型',
- PRIMARY KEY (`msg_id`,`to_id`),
- KEY `idx_from_circle` (`from_id`,`circle_id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
(编辑:晋中站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|