腾讯面试:腾讯面试过的MySQL场景问题

今天我将那些腾讯面试过的 MySQL 场景问题给大家整理出来,本文将跟大家一起来探讨如何回答这些问题。

1.一个 6 亿的表 a,一个 3 亿的表 b,通过外间 tid 关联,你如何最快的查询出满足条件的第 50000 到第 50200 中的这 200 条数据记录?

2.一条 sql 执行过长的时间,你如何优化,从哪些方面入手?

3.索引已经建好了,那我再插入一条数据,索引会有哪些变化?

4.mysql 的是怎么解决并发问题的?

5.MySQL 两个线程的 update 语句同时处理一条数据,会不会有阻塞?

6.两条 update 语句处理一张表的不同的主键范围的记录,一个 < 10,另一个 > 15,会不会遇到阻塞?

7.如果 Explain 用到的索引不正确的话,有什么办法干预吗?

8.给你张表,发现查询速度很慢,你有哪些解决方案?

9.关心过业务系统里面的 sql 耗时吗?统计过慢查询吗?对慢查询都怎么优化过?(explain)?

一个 6 亿的表 a,一个 3 亿的表 b,通过外间 tid 关联,你如何最快的查询出满足条件的第 50000 到第 50200 中的这 200 条数据记录?

这是一道腾讯的面试题,其实这个问题和上面是同一个问题,都是超大分页的问题,这就像读书的时候做数学题一样,上面是公式、定理,下面是题目,所以要学会举一反三。

  1. 如果 A 表 TID 是自增长,并且是连续的,B 表的 ID 为索引
sql 体验AI代码助手 代码解读复制代码select * from a,b where a.tid = b.id and a.tid>500000 limit 200;

  1. 如果 A 表的 TID 不是连续的,那么就需要使用覆盖索引.TID 要么是主键,要么是辅助索引,B 表 ID 也需要有索引。
sql 体验AI代码助手 代码解读复制代码select * from b , (select tid from a limit 50000,200) a where b.id = a .tid;

一条 sql 执行过长的时间,你如何优化,从哪些方面入手?

查看是否涉及多表和子查询,优化 Sql 结构,如去除冗余字段,是否可拆表等

优化索引结构,看是否可以适当添加索引

数量大的表,可以考虑进行分离/分表(如交易流水表)

数据库主从分离,读写分离

explain 分析 sql 语句,查看执行计划,优化 sql

查看 Mysql 执行日志,分析是否有其他方面的问题

索引已经建好了,那我再插入一条数据,索引会有哪些变化?

插入新数据可能导致 B+树结构的调整和索引信息的更新,以保持 B+树的平衡性和正确性,这些变化通常由数据库系统自动处理,确保数据的一致性和索引的有效性。

如果插入的数据导致叶子节点已满,可能会触发叶子节点的分裂操作,以保持 B+树的平衡性。

mysql 的是怎么解决并发问题的?

锁机制:Mysql 提供了多种锁机制来保证数据的一致性,包括行级锁、表级锁、页级锁等。通过锁机制,可以在读写操作时对数据进行加锁,确保同时只有一个操作能够访问或修改数据。

事务隔离级别:Mysql 提供了多种事务隔离级别,包括读未提交、读已提交、可重复读和串行化。通过设置合适的事务隔离级别,可以在多个事务并发执行时,控制事务之间的隔离程度,以避免数据不一致的问题。

MVCC(多版本并发控制):Mysql 使用 MVCC 来管理并发访问,它通过在数据库中保存不同版本的数据来实现不同事务之间的隔离。在读取数据时,Mysql 会根据事务的隔离级别来选择合适的数据版本,从而保证数据的一致性。

MySQL 两个线程的 update 语句同时处理一条数据,会不会有阻塞?

如果是两个事务同时更新了 id = 1,比如 update ... where id = 1,那么是会阻塞的。因为 InnoDB 存储引擎实现了行级锁。

当 A 事务对 id =1 这行记录进行更新时,会对主键 id 为 1 的记录加 X 类型的记录锁,这样第二事务对 id = 1 进行更新时,发现已经有记录锁了,就会陷入阻塞状态。

两条 update 语句处理一张表的不同的主键范围的记录,一个 < 10,另一个 > 15,会不会遇到阻塞?

不会,因为锁住的范围不一样,不会形成冲突。(当然前提是,没有其他事务干预 且 使用索引没有进行全表扫描)

第一条 update sql 的话( id<10),锁住的范围是(-♾️,10);

第二条 update sql 的话(id >15),锁住的范围是(15,+♾️)。

追加问题,如果 2 个范围不是主键或索引?还会阻塞吗?

如果 2 个范围查询的字段不是索引的话,那就代表 update 没有用到索引,这时候触发了全表扫描,全部索引都会加行级锁,这时候第二条 update 执行的时候,就会阻塞了。

因为如果 update 没有用到索引,在扫描过程中会对索引加锁,所以全表扫描的场景下,所有记录都会被加锁,也就是这条 update 语句产生了 4 个记录锁和 5 个间隙锁,相当于锁住了全表。

如果 Explain 用到的索引不正确的话,有什么办法干预吗?

可以使用 force index,强制走索引。

sql 体验AI代码助手 代码解读复制代码explain select name,price
from products
force index (idx_price)
where price between 10 and 80
orderby by price;

给你张表,发现查询速度很慢,你有哪些解决方案?

如果面试遇到了这样相似的问题,如优化查询速度,可以选择下面的几条来回答。

分析查询语句:使用 explain 命令分析 sql 执行计划,找出慢查询的原因,比如是否使用了全表扫描,是否存在索引未被使用的情况等,并根据相应情况对索引进行适当修改。

创建或优化索引:根据查询条件创建合适的索引,特别是经常用于 where 子句的字段、orderby 排序字段、join 连表查询的字典、group by 的字段,并且如果查询中经常涉及多个字段,考虑创建联合索引,使用联合索引要符合最左匹配原则,不然会索引失效

避免索引失效:比如不要用左模糊匹配、函数计算、表达式计算等等

查询优化:避免使用 select *,只查询真正需要的列;使用覆盖索引,即索引包含所有查询的字段;连表查询最好要以小表驱动大表,并且被驱动表的字段要有索引,当然最好通过冗余字段的设计,彼岸连表查询。

分页优化:针对 limit n,m 深分页的查询优化,可以把 limit 查询转换成某个位置的查询:select * from product where id> 20000 limit 10 ,该方案适用于主键自增的表

优化数据库表:如果单表的数据超过了千万级别,考虑是否需要将大表拆分为小表,减轻单个表的查询压力。也可以将字段多的表分解成多个表,有些字段使用频率高,有些低,数据量大时,会由于使用频率低的存在而变慢,可以考虑分开。

使用缓存技术:引入缓存层,如 redis,存储热点数据和频繁查询的结果,但是考虑缓存一致性的问题,对于读请求会选择旁路缓存策略,对于写请求会选择先更新数据库,再删除缓存的策略。

关心过业务系统里面的 sql 耗时吗?统计过慢查询吗?对慢查询都怎么优化过?(explain)?

在业务系统中,除了使用主键进行的查询,其他的我都会在测试库上测试其耗时,慢查询的统计主要由运维在做,会定期将业务中的慢查询反馈给我们。

慢查询的优化首先要搞明白慢的原因是什么? 是查询条件没有命中索引?是 load 了不需要的数据列?还是数据量太大?

所以优化也是针对这三个方向来的,

首先分析语句,看看是否 load 了额外的数据,可能是查询了多余的行并且抛弃掉了,可能是加载了许多结果中并不需要的列,对语句进行分析以及重写。

分析语句的执行计划(explain),然后获得其使用索引的情况,之后修改语句或者修改索引,使得语句可以尽可能的命中索引。

如果对语句的优化已经无法进行,可以考虑表中的数据量是否太大,如果是的话可以进行横向或者纵向的分表。

全部评论
谢谢佬
点赞 回复 分享
发布于 昨天 15:20 浙江
大佬这是第几面
点赞 回复 分享
发布于 06-16 12:19 陕西
wangzhongyang1993
点赞 回复 分享
发布于 06-11 17:07 北京

相关推荐

#&nbsp;Q48.如何判断链表有环#&nbsp;Q49.HashMap的扩容机制,容量为16,有12个数据,怎样判断有多少数据是链表,多少个数据存储在数组里#&nbsp;Q50.ConcurrentHashMap的size()方法#&nbsp;Q51.HashTable的底层、跟synchronizedMap、ConcurrentHashMap的区别#&nbsp;Q52.垃圾判定算法#&nbsp;Q53.被可达性分析法判定是不可达的垃圾什么时候回收?#&nbsp;Q54.垃圾回收器有那些#&nbsp;Q55.三个String字符串用+来拼接,时间复杂度是多少?StringBuff跟StringBuilder的区别#&nbsp;Q56.HTTP跟HTTPS的区别#&nbsp;Q57.TLS是对称加密还是非对称加密的?你还了解那些非对称加密算法#&nbsp;Q58.你了解那些双向验证的加密算法#&nbsp;Q59.你了解AIP吗?(不了解)知道NIO,你说说NIO#&nbsp;Q60.NIO的非阻塞是如何实现的?#&nbsp;Q61.select跟epoll的区别#&nbsp;Q62.为什么select只能用于小场景#&nbsp;Q63.FD_SETSIZE能被修改吗?我解释了一下FD是什么#&nbsp;Q64.MySQL的数据引擎有那些?有什么区别?#&nbsp;Q65.Redis高性能怎么实现?#&nbsp;Q66.主从节点如何选举新的主节点?#&nbsp;Q67.分区集群如何添加新节点#&nbsp;Q68.假设迁移的数据量很大,怎么优化?#&nbsp;Q69.zset的底层结构?除了跳表还有啥?#&nbsp;Q70.Redis淘汰策略#&nbsp;Q71.你的用户登录怎么实现的?怎样加密?#&nbsp;Q72.假如你的Token被劫持了,号主如何找回账号#&nbsp;Q73.异常地址登陆法验证码,IP地址伪造,用MAC地址来防止多个登录,MAC被伪造怎么办?每次登录发送手机验证码,会不会压力太大?#&nbsp;Q74.你购物车怎么实现的?(购物车记录用MySQL存)#&nbsp;Q75.购物车数据量太大怎么办#&nbsp;Q76.用户id进行hash分片行不行?分库分表?读写压力大怎么办?购物车服务独立#&nbsp;Q77.怎样上传商品图片跟用户头像#&nbsp;Q78.如何防止用户多次上传同一张图片?#&nbsp;Q79.如何防止多个用户上传同一张图片#&nbsp;Q80.手撕:十进制转六进制#&nbsp;Q91.反问#&nbsp;A:Q:有那些地方需要加强?A:核心:对于开发性的问题需要有更深入的了解Q:购物车方案怎么做?A:不写DB,客户端存储,数据同步,主要信息做一个缓存(有时效性)。.Q:Minio问题怎么解决?A:minio处理小文件框架,做一个文件系统,比对二进制编码Q:后续流程A:一周内最慢三个星期因为没有录屏,所以很多问题都是大概印象,牛友们将就着看把,我也是面完第一时间记录下来了面试感受:面试非常非常难,这是我的第一感受,面试官深挖了非常多的底层原理,以上是大部分,还有一些忘记了,因为整个面试过程压力爆大。面试官很专业,在我说出底层原理的时候又会问一些具体的东西,比如说我在说到select适合小场景适用时,面试官马上问为什么适合小场景?我说FD_SETSIZE数量只有1024,他问FD_SETSEZE可不可以变。根据我的回答来动态深挖你的知识储备跟场景业务理解。非常感谢面试官,因为有很多东西在他的引导下我慢慢加强的对业务跟场景的理解大家找实习生工作时,面试有遇到这种面试官吗?欢迎留言,记得给主播点赞。下Offer第一时间更新,祝牛友们找到合适心仪的工作。
点赞 评论 收藏
分享
评论
8
41
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务