在MySQL中,如何定位慢查询?
表象:页面加载过慢、接口压测响应时间过长(超过1s)
1.介绍一下当时产生问题的场景(我们当时的一个接口测试的时候非常的慢,压测的结果大概5秒钟)
2.我们系统中当时采用了运维工具 ( Skywalking ),可以监测出哪个接口,最终因为是sql的问题
3.在mysql中开启了慢日志查询,我们设置的值就是2秒,一旦sql执行超过2秒就会记录到日志中(调试阶段)
方案一:开源工具
调试工具:Arthas
运维工具: Prometheus 、Skywalking
方案二: MySQL自带慢日志
慢查询日志记录了所有执行时间超过指定参数 (long_query_time,单位:秒,默认10秒)的所有SQL语句的日志如果要开启慢查询日志,需要在MySQL的配置文件(etc/my.cnf)中配置如下信息:
开启MySQL慢日志查询开关
slow query log=1
设置慢日志的时间为2秒,SQL语句执行时间超过2秒,就会视为慢查询,记录慢查询日志
long_query_time=2
配置完毕之后,通过以下指令重新启动MySQL服务器进行测试,查看慢日志文件中记录的信息/var/lib/mysql/localhost-slow.log。
那这个SQL语句执行很慢,如何分析呢?
可以采用MySQL自带的分析工具 EXPLAIN
通过key和key len检查是否命中了索引(索引本身存在是否有失效的情况)。
通过type字段查看sql是否有进一步的优化空间,是否存在全索引扫描或全盘扫描。
通过extra建议判断,是否出现了回表的情况,如果出现了,可以尝试添加索引或修改返回字段来修复。
了解过索引吗?(什么是索引)
索(index)是帮助MySQL高效获取数据的数据结构(有序)
提高数据检索的效率,降低数据库的IO成本(不需要全表扫描)
通过索引列对数据进行排序,降低数据排序的成本,降低了CPU的消耗
索引的底层数据结构了解过嘛?
MySQL的InnoDB引擎采用的B+树的数据结构来存储索引
阶数更多,路径更短
磁盘读写代价B+树更低,非叶子节点只存储指针,叶子阶段存储数据
B+树便于扫库和区间查询,叶子节点是一个双向链表
什么是聚簇索引什么是非聚簇索引?
聚簇索引(聚集索引):数据与索引放到一块,B+树的叶子节点保存了整行数据,有且只有一个。
非聚簇索引(二级索引):数据与索引分开存储,B+树的叶子节点保存对应的主键,可以有多个
知道什么是回表查询嘛?
通过二级索引找到对应的主键值,到聚集索引中查找整行数据,这个过程就是回表。
覆盖索引
覆盖索引是指查询使用了索引,返回的列,必须在索引中全部能够找到
使用id查询,直接走聚集索引查询,一次索引扫描,直接返回数据,性能高。
如果返回的列中没有创建索引,有可能会触发回表查询,尽量避免使用select * 。
MYSQL超大分页怎么处理?
问题:在数据量比较大时,limit分页查询,需要对数据进行排序,效率低解决方案:覆盖索引+子查询。
优化思路: 一般分页查询时,通过创建覆盖索引 能够比较好地提高性能,可以通过覆盖索引加子查询形式进行优化
select
from tb sku t,
(select id from tb sku order by id limit 9000000,10) a where t.id = a.id:
索引创建原则有哪些?
1).数据量较大,且查询比较频繁的表
2).常作为查询条件、排序、分组的字段
3).字段内容区分度高
4).内容较长,使用前缀索引
5).尽量联合索引,防止回表
6). 要控制索引的数量
7). 如果索引列不能存储NULL值,请在创建表时使用NOT NULL约束它
什么情况下索引会失效 ?
1.违反最左前缀法则
2.范围查询右边的列,不能使用索引
3.不要在索引列上进行运算操作,索引将失效
4.字符串不加单引号,造成索引失效。(类型转换)
5.以%开头的Like模糊查询,索引可能失效,覆盖索引不失效
谈一谈你对sql的优化的经验
1.表的设计优化,数据类型的选择
2.索引优化,索引创建原则
3.sql语句优化,避免索引失效,避免使用select *,小表驱动大表
4.主从复制、读写分离,不让数据的写入,影响读操作
5.分库分表
事务的特性是什么?可以详细说一下吗?
原子性( Atomicity)
一致性( Consistency )
隔离性(lsolation )
持久性( Durability )
结合转账案例进行说明
面试官:事务的特性是什么?可以详细说一下吗?
候选人:嗯,这个比较清楚,ACID,分别指的是:原子性、一致性、隔离性、持久性:我举个例子:A向B转账500,转账成功,A扣除500元,B增加500元,原子操作体现在要么都成功,要么都失败在转账的过程中,数据要一致,A扣除了500,B必须增加500在转账的过程中,隔离性体现在A像B转账,不能受其他事务干扰在转账的过程中,持久性体现在事务提交后,要把数据持久化(可以说是落盘操作)
并发事务带来哪些问题? 怎么解决这些问题呢? MySQL的默认隔离级别是?
并发事务的问题:
1.脏读:一个事务读到另外一个事务还没有提交的数据
2.不可重复读:一个事务先后读取同一条记录,但两次读取的数据不同
3.幻读:一个事务按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了”幻影”。
隔离级别:
1.READ UNCOMMITTED 未提交读脏读
2.READ COMMITTED 读已提交
3.REPEATABLE READ 可重复读 (MYSQL默认隔离级别)
4.SERIALIZABLE 串行化