关于面试 MySQL 的疑问

2023-05-31 17:51:21 +08:00
 gps32251070

最近的一次面试,面试官提到了一个 MySQL 场景,如下


表 t 只有两个字段,主键 id 和 varchar 类型的 name ,现在有一条 SQL:select id,name from t limit 2; 这条语句执行过程中很慢,问大概的原因。


思考了一下,感觉不是锁问题,所以答了下大概是服务器负载大,查询的 SQL 很多都是不重复的,导致数据页缓存命中有问题之类的,面试官不是很满意这个答案,后面快结束我又问了下这个问题,面试官回答大概意思是负载导致的锁的问题。

我的疑问是,这个 sql 语句不是走的快照读吗?又没有加 lock in share mode ,其他语句的锁怎么会影响到它的执行呢?还有一个可能是加了 MDL 写锁,但是 MDL 写锁在修改表结构的情况下才会发生,生产环境基本不会出现。有没有懂的老哥帮忙解答下?

3413 次点击
所在节点    程序员
58 条回复
ModStart
2023-05-31 21:34:37 +08:00
1. 数据量过大:如果表 t 中的数据量非常庞大,那么执行这条 SQL 语句会涉及大量的数据读取操作,导致执行时间变长。
2. 索引缺失:如果在表 t 上没有合适的索引,数据库系统将需要进行全表扫描来查找满足条件的数据,这会导致执行时间延长。
3. 硬件性能问题:如果数据库服务器的硬件性能较低,如 CPU 、内存、磁盘速度等方面的限制,可能导致执行 SQL 语句的速度变慢。
4. 锁竞争:如果在执行这条 SQL 语句的同时,有其他的查询或写操作正在对表 t 进行操作,并且涉及到了相同的数据行,那么就可能发生锁竞争,导致执行速度变慢。
gps32251070
2023-05-31 21:35:12 +08:00
@xiaofan2 innodb ,RR 级别,面试官意思强调是锁导致的,我理解这个语句锁是不会导致慢的,唯一可能的是数据页 buffer 频繁被替换
gps32251070
2023-05-31 21:37:13 +08:00
@sadfQED2 他意思是高负载导致的锁等待
JasonLaw
2023-05-31 21:53:26 +08:00
@sadfQED2 #37 这已经脱离了语句本身,网络不行,什么都会慢。还是那句话,这个题目和面试官都很傻逼。
hangszhang
2023-05-31 22:15:13 +08:00
锁表可还行,快照读又不加锁
doraf
2023-05-31 22:21:11 +08:00
也可能有这种情况:
https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html
SERIALIZABLE 这段,This level is like REPEATABLE READ, but InnoDB implicitly converts all plain SELECT statements to SELECT ... FOR SHARE if autocommit is disabled.
rekulas
2023-05-31 23:25:21 +08:00
锁导致的问题。。。有没可能是这样
面试官也是技术,内部系统某些逻辑设计不合理为了避免冲突直接锁表更新数据,完了再解锁
负载上来之后面试官发现这样的频繁加解锁操作会导致 select 明显变慢,一时狂喜,又发现一个 mysql 缺陷,于是用来作为考题测试来面试的“小白”们能否快速分析出原因
urnoob
2023-05-31 23:32:09 +08:00
首先说没索引导致肯定不对,因为主键默认就是索引的。
除了网络等外部情况,可能性最大的是大量比当前 id 还小的数据插入,特别是插入的 id 还是递减的,导致树最左边的节点在不断分裂,一直会有锁。
yagamil
2023-06-01 00:11:49 +08:00
可能是索引 id 是乱序的? 然后面试其实想考的 limit x,y ; 在数量巨大的情况下的性能问题?
Weixiao0725
2023-06-01 00:22:18 +08:00
要我回答就说这个 mysql 一定是运行在 20 年前的机器上
Euthpic
2023-06-01 01:36:46 +08:00
这个问题有点傻 x ,因为慢的原因和 sql 无关,原因可能出在 mysql ,网络,硬盘等系统方面。给出具体 sql 的目的是觉得这个 sql 可以优化吗?
nuk
2023-06-01 03:01:29 +08:00
遇到过两种情况,一种是卡 io ,还有一种很奇怪,是某个客户端执行语句,sql 协议出问题,一直在等几个 byte ,然后整个表就处于锁死的状态。
akira
2023-06-01 05:33:53 +08:00
其实问题是问,一个明显不可能慢的 sql 执行很慢,有什么可能。
dog82
2023-06-01 09:19:04 +08:00
如果 mysql 的事务隔离级别被设置成串行化,会频繁出现!
但是谁傻到设置成串行化呢
leorealman
2023-06-01 09:46:09 +08:00
磁盘 IO 被打满是可能会这样的
plutome
2023-06-01 10:29:48 +08:00
@xuanbg

“ 20 万里取 2 条的意思是先读 20 万,然后取 2 条啊,不是直接取 2 条!”
“ limit 2 是顺序读 2 条没错,可顺序怎么来的?不得排序先?”

虽然我自己也经常犯这种“眼高手低”的错误,但是这两句话说得还是离谱。 可能还是要多学习一下。
Pythoner666666
2023-06-01 13:54:24 +08:00
@xuanbg 兄弟 这个说法就很离谱啊 ,你一边让别人去尝试,可是你自己就是不去真的尝试一下
8355
2023-06-01 18:38:38 +08:00
可能是面试官沟通能力有问题.
这样问法绝大部分正常人的理解应该是在场景正常的情况下因为这条 sql 本身执行慢是什么原因,
如果说因为其他原因的慢是过于开放性的答案了.面试官应该给予合理引导.

可以从负载和 io 上回答 也可以从锁上回答. 也可以从各种不合理应用回答.
也可以从数据量上回答,也可以从表引擎上回答,也可以从数据库配置回答
还可以通过网络原因上回答.
都他妈可能影响慢.🤡

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/944619

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX