美团面试题:慢SQL有遇到过吗?是怎么解决的?
moboyou 2025-03-14 16:31 12 浏览
大家好,我是田维常,可以叫我老田,也可以叫我田哥
。2017年的时候,我刚去上海,朋友内推我去美团面试,之前我也写过一个一篇文章,也是在美团面试中遇到的:
美团面试题:String s = new String("111")会创建几个对象?
关于慢SQL,我和面试官扯了很久,面试官也是很谦虚的,总是点头,自己以为回答的还可以。最后的最后,还是说了“你先回去等通知吧!”。
所以,我决定把这个慢SQL技术点,好好和你分享分享。希望你下次在遇到类似的面试,能顺顺利利轻轻松松的斩获自己想要的offer。
人生最大的喜悦是每个人都说你做不到,你却完成它了!
什么是慢SQL?
MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录MySQL中查询时间超过(大于)设置阈值(long_query_time)的语句,记录到慢查询日志中。
其中,long_query_time的默认值是10,单位是秒,也就是说默认情况下,你的SQL查询时间超过10秒就算慢SQL了。
如何开启慢SQL日志?
在MySQL中,慢SQL日志默认是未开启的,也就说就算出现了慢SQL,也不会告诉你的,如果需要知道哪些SQL是慢SQL,需要我们手动开启慢SQL日志的。
关于慢SQL是否开启,我们可以通过下面这个命令来查看:
-- 查看慢查询日志是否开启
show variables like '%slow_query_log%';
在这里插入图片描述
通过命令,我们就可以看到slow_query_log项为OFF,说明我们的慢SQL日志并未开启。另外我们也可以看到我们慢SQL日志存放于哪个目录下和日志文件名。
下面我们来开启慢SQL日志,执行下面的命令:
set global slow_query_log = 1;
这里需要注意,这里开启的是我们当前的数据库,并且,我们重启数据库后会失效的。
开启慢SQL日志后,再次查看:
slow_query_log项已经变成ON,说明开启成功。
上面说过慢SQL默认时间是10秒,我们通过下面的命令就可以看到我们慢SQL的默认时间:
show variables like '%long_query_time%';
在这里插入图片描述
我们总不能一直使用这个默认值,可能很多业务需要时间更短或更长,所以此时,我们就需要对默认时间进行修改,修改命令如下:
set long_query_time = 3;
修改完了,我们再来看看是否已经改成了3秒。
这里需要注意:想要永久的生效,还需要修改MySQL下面的配置文件my.cnf 文件。
[mysqld]
slow_query_log=1
slow_query_log_file=/var/lib/mysql/atguigu-slow.log
long_query_time=3
log_output=FILE
注意:不同操作系统,配置有些区别。
Linux操作系统中
在mysql配置文件my.cnf中增加
log-slow-queries=/var/lib/mysql/slowquery.log (指定日志文件存放位置,可以为空,系统会给一个缺省的文件host_name-slow.log)
long_query_time=2 (记录超过的时间,默认为10s)
log-queries-not-using-indexes (log下来没有使用索引的query,可以根据情况决定是否开启)
log-long-format (如果设置了,所有没有使用索引的查询也将被记录)
Windows操作系统中
在my.ini的[mysqld]添加如下语句:
log-slow-queries = E:\web\mysql\log\mysqlslowquery.log
long_query_time = 3(其他参数如上)
执行一条慢SQL,因为我们前面已经设置好了慢SQL时间为3秒,所以,我们只要执行一条SQL时间超过3秒即可。
SELECT SLEEP(4);
该SQL耗时4.024秒,下面我们就来查看慢SQL出现了多少条。
使用命令:
show global status like '%Slow_queries%';
查询SQL历程
找到慢SQL日志文件,打开后就会出现类似下面这样的语句;
# Time: 2021-07-20T09:17:49.791767Z
# User@Host: root[root] @ localhost [] Id: 150
# Query_time: 0.002549 Lock_time: 0.000144 Rows_sent: 1 Rows_examined: 4079
SET timestamp=1566292669;
select * from city where Name = 'Salala';
简单说明:
1.Time 该日志记录的时间
2.User @Host MySQL登录的用户和登录的主机地址
3.Query_time一行 第一个时间是查询的时间、第二个是锁表的时间、第三个是返回的行数、第四个是扫描的行数
4.SET timestamp 这一个是MySQL查询的时间
5.sql语句 这一行就很明显了,表示的是我们执行的sql语句
切记
如果你将long_query_time=0 ,那就意味着,我们所有的查询SQL语句都会输出到慢SQL日志文件中。
如何定位慢SQL?
通常我们定位慢SQL有两种方式:
第一种:定位慢查询SQL可以通过两个表象进行判断
- 系统级表象:
- 使用sar命令和top命令查看当前系统的状态
- 也可以使用Prometheus和Grafana监控工具查看当前系统状态
- CPU消耗严重
- IO等待严重
- 页面响应时间过长
- 项目日志出现超时等错误
- SQL语句表象:
- SQL语句冗长
- SQL语句执行时间过长
- SQL从全表扫描中获取数据
- 执行计划中的rows和cost很大
第二种:根据不同的数据库使用不同的方式获取问题SQL
- MySQL:
- 慢查询日志
- 测试工具loadrunner
- ptquery工具
- Oracle:
- AWR报告
- 测试工具loadrunner
- 相关内部视图vsession_wait
- GRID CONTROL监控工具
熟悉慢SQL日志分析工具吗?
如果开启了慢SQL日志后,可能会有大量的慢SQL日志产生,此时再用肉眼看,那是不太现实的,所以大佬们就给我搞了个工具:mysqldumpslow。
mysqldumpslow能将相同的慢SQL归类,并统计出相同的SQL执行的次数,每次执行耗时多久、总耗时,每次返回的行数、总行数,以及客户端连接信息等。
通过命令
mysqldumpslow --help
可以看到相关参数的说明:
~# mysqldumpslow --help
Usage: mysqldumpslow [ OPTS... ] [ LOGS... ]
Parse and summarize the MySQL slow query log. Options are
--verbose verbose
--debug debug
--help write this text to standard output
-v verbose
-d debug
-s ORDER what to sort by (al, at, ar, c, l, r, t), 'at' is default
al: average lock time
ar: average rows sent
at: average query time
c: count
l: lock time
r: rows sent
t: query time
-r reverse the sort order (largest last instead of first)
-t NUM just show the top n queries
-a don't abstract all numbers to N and strings to 'S'
-n NUM abstract numbers with at least n digits within names
-g PATTERN grep: only consider stmts that include this string
-h HOSTNAME hostname of db server for *-slow.log filename (can be wildcard),
default is '*', i.e. match all
-i NAME name of server instance (if using mysql.server startup script)
-l don't subtract lock time from total time
比较常用的参数有这么几个:
-s 指定输出的排序方式
t : 根据query time(执行时间)进行排序;
at : 根据average query time(平均执行时间)进行排序;(默认使用的方式)
l : 根据lock time(锁定时间)进行排序;
al : 根据average lock time(平均锁定时间)进行排序;
r : 根据rows(扫描的行数)进行排序;
ar : 根据average rows(扫描的平均行数)进行排序;
c : 根据日志中出现的总次数进行排序;
-t 指定输出的sql语句条数;
-a 不进行抽象显示(默认会将数字抽象为N,字符串抽象为S);
-g 满足指定条件,与grep相似;
-h 用来指定主机名(指定打开文件,通常慢查询日志名称为“主机名-slow.log”,用-h exp则表示打开exp-slow.log文件);
使用方式
mysqldumpslow常用的使用方式如下:
# mysqldumpslow -s c slow.log
如上一条命令,应该是mysqldumpslow最简单的一种形式,其中-s参数是以什么方式排序的意思,c指代的是以总数从大到小的方式排序。-s的常用子参数有:c: 相同查询以查询条数和从大到小排序。t: 以查询总时间的方式从大到小排序。l: 以查询锁的总时间的方式从大到小排序。at: 以查询平均时间的方式从大到小排序。al: 以查询锁平均时间的方式从大到小排序。
同样的,还可以增加其他参数,实际使用的时候,按照自己的情况来。
其他常用方式:
# 得到返回记录集最多的10 个SQL
mysqldumpslow -s r -t 10 /var/lib/mysql/atguigu-slow.log
# 得到访问次数最多的10 个SQL
mysqldumpslow -s c -t 10 /var/lib/mysql/atguigu-slow.log
# 得到按照时间排序的前10 条里面含有左连接的查询语句
mysqldumpslow -s t -t 10 -g "left join" /var/lib/mysql/atguigu-slow.log
# 另外建议在使用这些命令时结合| 和more 使用,否则有可能出现爆屏情况
mysqldumpslow -s r -t 10 /var/lib/mysql/atguigu-slow.log | more
接下,我们来个实际操作。
实操
root@yunzongjitest1:~# mysqldumpslow -s t -t 3
Reading mysql slow query log from /var/lib/mysql/exp-slow.log /var/lib/mysql/yunzongjitest1-slow.log
Count: 464 Time=18.35s (8515s) Lock=0.01s (3s) Rows=90884.0 (42170176), root[root]@localhost
select ************
Count: 38 Time=11.22s (426s) Lock=0.00s (0s) Rows=1.0 (38), root[root]@localhost
select *********** not like 'S'
Count: 48 Time=5.07s (243s) Lock=0.02s (1s) Rows=1.0 (48), root[root]@localhost
select ********='S'
这其中的SQL语句因为涉及某些信息,所以我都用*号将主体替换了,如果希望得到具体的值,使用-a参数。
使用mysqldumpslow查询出来的摘要信息,包含了这些内容:
Count: 464 :表示慢查询日志总共记录到这条sql语句执行的次数;
Time=18.35s (8515s):18.35s表示平均执行时间(-s at),8515s表示总的执行时间(-s t);
Lock=0.01s (3s):与上面的Time相同,第一个表示平均锁定时间(-s al),括号内的表示总的锁定时间(-s l)(也有另一种说法,说是表示的等待锁释放的时间);
Rows=90884.0 (42170176): 第一个值表示扫描的平均行数(-s ar),括号内的值表示扫描的总行数(-s r)。
是不是
so easy!!!!
来源:
https://mp.weixin.qq.com/s/Cuv8zwDmFSzp9DGqEw8zhg作者:田维常
相关推荐
- 产品页不显示价格?用这招让独立站转化率翻倍
-
“客户急得直拍桌子:‘为什么美国用户点进来看不到价格?’”建站设计师小夏盯着屏幕上的报错提示——结构化数据没写对,Google爬虫根本没抓到价格信息。这是一家卖手工珠宝的跨境店,主推定制款,价格因材质...
- FOGProject 1.5.10 开源 可以使用PXE、PartClone和Web GUI
-
FOGProject起点介绍FOG是一个免费的开源克隆/镜像/救援套件/库存管理系统。FOG可以使用PXE、PartClone和WebGUI来对WindowsXP、Vista、Windows7...
- AI+隐私计算:淘宝API的下一站,数据开放与安全的双重革命
-
淘宝API分类全解析:从商品管理到智能营销的接口生态引言在电商行业数字化转型中,淘宝API(ApplicationProgrammingInterface)作为连接平台与开发者的技术桥梁,已成为实...
- PHP MySQLi基础教程 MySQL 创建数据库
-
数据库存有一个或多个表。你需要CREATE权限来创建或删除MySQL数据库。使用MySQLi和PDO创建MySQL数据库CREATEDATABASE语句用于在MySQL中创...
- PHP跑不动?服务器慢成蜗牛,客户投诉不断.
-
最近公司电商系统总卡,用户下单页面半天打不开,客服电话快被打爆。技术主管说PHP性能不行,我们几个新来的程序员被拉来紧急开会。老王翻出一本破旧的《高性能PHP开发》说:"这本书早该读了"...
- PHP+UniApp:低成本打造外卖系统横扫App+小程序+H5全平台
-
在餐饮行业数字化转型中,外卖系统开发常面临两大痛点:高昂的开发成本(需独立开发App、小程序、H5)和多端维护的复杂性。PHP+UniApp的组合通过技术复用与跨平台能力,为中小商家和开发者提供了“降...
- PHP分布式锁超卖方案以及高并发优化
-
在PHP的生态中,是通过多进程的方式去优化程序性能的。在单机架构情况下防止超卖不像JAVA那样可以使用自身的锁机制实现。需要借助第三方程序来实现,如:数据库、Redis等。接下来我们通过一个基于Re...
- PHP实战经验之系统如何支撑高并发
-
高并发系统各不相同。比如每秒百万并发的中间件系统、每日百亿请求的网关系统、瞬时每秒几十万请求的秒杀大促系统。他们在应对高并发的时候,因为系统各自特点的不同,所以应对架构都是不一样的。另外,比如电商平台...
- PHP高并发架构:三招让Redis与MySQL数据强同步(含黑科技方案)
-
技术段位:百万级并发架构师必修实战价值:数据不一致窗口期<50ms|零代码侵入方案|抗亿级流量冲击一、颠覆认知:99%的项目在用错误方案(你中招了吗?)1.经典双删策略的致命缺陷//...
- 基于Python的仓库库存管理系统的设计和实现
-
《基于Python的仓库库存管理系统的设计和实现》该项目采用技术Python的django框架、mysql数据库,项目含有源码、论文、PPT、配套开发软件、软件安装教程、项目发布教程、核心代码介绍视...
- 如何在Redis中处理并发写入php电商网站库存超卖示例
-
经常会遇到需要在项目中处理并发的情况。今天就用redis来处理并发,解决电商项目中的库存超卖常见需求。项目背景电商网站需要处理高并发的购买请求,每个请求都会减少对应商品的库存数量。为了避免库存超卖,我...
- 【新书推荐】6.1 鼠标基础知识(鼠标的基础操作)
-
第六章鼠标Windows程序以其友好的用户交互体验著称。键盘和鼠标都是用户与Windows程序交互的工具。键盘一般被当作用来输入和管理文本数据的设备,鼠标则被看作是用来绘制和处理图形对象的设备。上一...
- FFmpeg学习(1)开篇(ffmpeg 教程)
-
FFmpeg学习(1)开篇FFmpeg学习(2)源码编译,环境配置为什么要学习FFmpeg本人希望打算深入研究音视频领域,音视频领域的内容很多,我自己打算从几方面循序渐进:FFmpeg常用功能实践,...
- 华纳云:服务器监控系统中最常用的性能指标有哪些
-
服务器监控系统通常用于监视服务器的性能和健康状况,以确保其正常运行并及时发现问题。以下是服务器监控系统中最常用的性能指标: 1.CPU使用率:CPU使用率是指服务器上的中央处理器(CPU...
- 实战线上 Linux 服务器深度优化指南
-
1.系统基础配置优化优化目标:建立统一、安全、稳定的系统基础环境,为后续优化奠定基础。1.1规范化主机命名采用"功能-地域-机房-机柜-编号"命名法,这样便于资产管理和定位。#采用...
- 一周热门
- 最近发表
- 标签列表
-
- 外键约束 oracle (36)
- oracle的row number (32)
- 唯一索引 oracle (34)
- oracle in 表变量 (28)
- oracle导出dmp导出 (28)
- oracle两个表 (20)
- oracle 数据库 字符集 (20)
- matlab化简多项式 (20)
- 多线程的创建方式 (29)
- 多线程 python (30)
- java多线程并发处理 (32)
- 宏程序代码一览表 (35)
- c++需要学多久 (25)
- css class选择器用法 (25)
- css样式引入 (30)
- css教程文字移动 (33)
- php简单源码 (36)
- php个人中心源码 (25)
- php小说爬取源码 (23)
- 云电脑app源码 (22)
- html画折线图 (24)
- docker好玩的应用 (28)
- linux有没有pe工具 (34)
- mysql数据库源码 (21)
- php开源万能表单系统源码 (21)