美团面试:Mysql 有几级缓存? 每一级缓存,具体是什么?

简介: 在40岁老架构师尼恩的读者交流群中,近期有小伙伴因未能系统梳理MySQL缓存机制而在美团面试中失利。为此,尼恩对MySQL的缓存机制进行了系统化梳理,包括一级缓存(InnoDB缓存)和二级缓存(查询缓存)。同时,他还将这些知识点整理进《尼恩Java面试宝典PDF》V175版本,帮助大家提升技术水平,顺利通过面试。更多技术资料请关注公号【技术自由圈】。

尼恩说在前面

在40岁老架构师 尼恩的读者交流群(50+)中,最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团、蚂蚁、得物的面试资格,遇到很多很重要的相关面试题:

Mysql 有几级缓存? 每一级缓存,具体是什么?

最近有小伙伴面试美团,都问到了这个面试题。 小伙伴没有系统的去梳理和总结,所以支支吾吾的说了几句,面试官不满意,面试挂了。

所以,尼恩给大家做一下系统化、体系化的梳理,使得大家内力猛增,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。

当然,这道面试题,以及参考答案,也会收入咱们的 《尼恩Java面试宝典PDF》V175版本,供后面的小伙伴参考,提升大家的 3高 架构、设计、开发水平。

《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请到文末公号【技术自由圈】获取

在 MySQL 数据库中,查询执行计划(MySQL Execution Plan)是决定查询性能的关键因素。

一个好的执行计划(MySQL Execution Plan)能够让查询高效地运行,减少资源的消耗和响应时间。

一、MySQL缓存机制概述

MySQL的缓存机制主要分为两种:一级缓存和二级缓存。

一级缓存

也称为InnoDB缓存,是MySQL的一种存储引擎(InnoDB)提供的缓存机制。它主要用于存储数据和索引,提高数据访问速度。

二级缓存:

也称为查询缓存(Query Cache),是MySQL服务器内部的缓存机制,用于存储SELECT查询的结果。当相同的查询再次执行时,可以直接从缓存中获取结果,而无需再次查询数据库。

二、MySQL 整体架构

Mysql的架构 ,整体是分为服务层、引擎层和文件系统层,其架构图如下所示:

image.png

MySQL Server 服务层(Service Layer)解析 SQL 语句、优化查询以及执行操作的,分别有三个关键组件完成:

  • 解析器(Parser)
  • 优化器(Optimizer)
  • 执行器(Executor)。

每个组件在查询执行的过程中扮演不同的角色,下面分别介绍这三者的作用:

1. 解析器(Parser)

解析器是 SQL 查询执行的第一步,它的职责是将用户发送的 SQL 语句解析为数据库能够理解的内部结构。

  • SQL 词法分析:解析器首先对 SQL 语句进行词法分析,将 SQL 语句分割成多个“单词”或“标记”,如表名、列名、关键字等。
  • 语法分析:接着,解析器会根据 SQL 语法规则生成对应的解析树(Parse Tree),用来描述 SQL 语句的逻辑结构。这个过程检查 SQL 语句的语法是否正确。
  • 语义分析:确认 SQL 语句中涉及的数据库对象是否存在(比如表名、字段名是否有效),并且检查权限。

解析完成后,生成一个中间表示结构,交由下一步进行处理。

2. 优化器(Optimizer)

优化器负责选择最优的执行计划,使查询能够以最高效的方式运行。

  • 逻辑优化:优化器会对 SQL 语句进行逻辑优化,比如 SQL 语句重写、消除冗余操作、合并重复条件、重新排列 WHERE 子句中的条件等。
  • 物理优化:在物理优化阶段,优化器会选择最优的访问路径和执行顺序。例如,它会决定使用哪种索引(如果有多个索引可选),是否做全表扫描,如何连接多张表(选择嵌套循环、哈希连接或排序合并连接等)。
  • 成本估算:优化器会基于数据库的统计信息(例如表的大小、索引的选择性等)来估算不同执行计划的成本,选择代价最低的执行方案。

经过优化后,优化器会生成一个查询执行计划,并交给执行器处理。

3. 执行器(Executor)

执行器的任务是按照优化器生成的执行计划,逐步执行查询,访问数据并返回结果。

  • 权限检查:在执行之前,执行器会首先检查用户是否有权限执行相应的操作。如果没有权限,则返回错误信息。
  • 执行执行计划:执行器根据生成的执行计划,依次调用存储引擎的接口来执行具体的操作。例如,如果是查询操作,执行器会调用存储引擎来读取相应的数据;如果是插入操作,执行器则会调用存储引擎来插入数据。
  • 结果返回:执行器根据查询的结果,将数据以合适的格式返回给客户端。如果涉及多个步骤(如 JOIN 操作),执行器会协调各个步骤的执行,并组合最终的结果集。

三个核心组件之间的交互流程

  1. 解析器:SQL 语句转换为解析树。
  2. 优化器:生成最优的执行计划。
  3. 执行器:根据计划调用存储引擎执行操作并返回结果。

这三个组件相互协作,完成从接收到 SQL 查询到返回结果的整个过程。

三:一条完成的sql查询语句 执行流程 ,如下所示:

image.png

一条完整的SQL查询语句从执行到返回结果的流程涉及到多个组件和步骤,其中可能包括缓存的使用。以下是执行流程的一般概述,以及可能用到的缓存:

  1. 客户端请求:

    客户端(如应用程序)向MySQL服务器发送SQL查询请求。

  2. 解析器:

    MySQL服务器接收到SQL查询后,首先由解析器进行解析,检查SQL语句的语法是否正确。

  3. 优化器:

    解析完成后,优化器会根据查询语句和数据库的元数据(如表结构、索引等)生成一个或多个执行计划。

  4. 权限检查:

    服务器检查执行该查询的用户是否有相应的权限。

  5. 缓存查询:

    在某些情况下,如果查询可以被缓存,服务器会检查一级缓存(如InnoDB缓冲池)和/或二级缓存(如果启用了查询缓存)。

    二级缓存(查询缓存,MySQL 8.0之前):如果查询缓存启用,服务器会检查查询缓存中是否有该查询的结果。如果有,直接返回缓存结果。

  6. 执行器:

    如果查询没有在缓存中找到,执行器会根据优化器生成的执行计划执行查询。

    执行过程中,可能会涉及到数据的读取和写入操作,此时二级缓存(InnoDB缓冲池)会更新。

    一级缓存(InnoDB缓冲池):如果查询涉及到的数据或索引页已经在缓冲池中,可以直接使用,无需访问磁盘。

  7. 返回结果:

    查询执行完成后,结果集被返回给客户端。

  8. 更新缓存:

    对于写操作(如INSERT、UPDATE、DELETE),相关的缓存(一级缓存和查询缓存)需要被更新或失效,以保持数据的一致性。

  9. 日志记录:

    服务器会记录查询的日志信息,如慢查询日志,用于后续的性能分析。

  10. 关闭连接:

    查询完成后,客户端可以选择关闭与MySQL服务器的连接,或者保持连接以便于后续的查询。

需要注意的是,从MySQL 8.0开始,查询缓存已经被移除,因此在使用MySQL 8.0及更高版本时,不会使用到查询缓存。

此外,二级缓存(如InnoDB缓冲池)的使用是自动的,由InnoDB存储引擎管理,不需要用户干预。用户可以通过调整缓冲池的大小和其他相关参数来优化其性能。

四:MySQL 8.0 版本为何移出了二级缓存(Query Cache)?

MySQL 8.0 版本中已经完全移除了查询缓存(Query Cache)功能。在早期的MySQL版本中,查询缓存是一个用于存储SELECT查询结果的内存区域,以提高重复查询的性能。然而,由于查询缓存在某些情况下会导致性能问题,特别是在高并发和写密集型的应用场景中,查询缓存可能会频繁失效,导致缓存命中率低,反而增加了性能开销。

因此,MySQL 8.0及更高版本推荐使用其他缓存策略,比如:

  1. 应用层缓存:在应用代码中实现缓存逻辑,使用如Redis、Memcached等缓存系统。
  2. 持久化存储引擎缓存:利用InnoDB的缓冲池来缓存数据和索引。
  3. 其他存储引擎:如果需要查询缓存的功能,可以考虑使用支持查询缓存的存储引擎,如MyISAM(但MyISAM不支持事务)。

MySQL 8.0通过优化存储引擎和索引管理,以及提供更好的性能调优工具和特性,来提高查询性能,而不是依赖于查询缓存。

五:MySQL 8.0 版本前的二级缓存配置

可以通过下面的步骤,进行二级缓存配置
步骤 描述 代码
1 启用查询缓存 SET GLOBAL query_cache_type = 1;
2 设置查询缓存大小 SET GLOBAL query_cache_size = 64 * 1024 * 1024;
3 执行查询 SELECT * FROM table_name;
代码解释
  • SET GLOBAL query_cache_type = 1;:启用查询缓存,1表示ON。
  • SET GLOBAL query_cache_size = 64 * 1024 * 1024;:设置查询缓存的大小,这里设置为64MB。
  • SELECT * FROM table_name;:执行查询,如果查询缓存中存在相同的查询,将直接从缓存中获取结果。

六:使用应用层的缓存作为 外置缓存

需要注意的是,MySQL 8.0版本中已经移除了查询缓存(Query Cache),因为其在某些情况下会导致性能问题,比如在高并发写入的场景下,查询缓存可能会频繁失效,导致缓存命中率低,反而增加了性能开销。

MySQL 8.0推荐使用其他缓存策略,比如使用应用层的缓存(如Redis、Memcached)作为 外置缓存,加速热点数据的访问。

对于需要缓存的场景,可以考虑以下几种替代方案:

  • 应用层缓存:在应用代码中实现缓存逻辑,使用如Redis、Memcached等缓存系统。
  • 本地缓存: 对与热点数据,可以是用本地缓存对数据进行cache。

尼恩架构团队的塔尖 sql 面试题

  • sql查询语句的执行流程:

网易面试:说说MySQL一条SQL语句的执行过程?

  • 索引

阿里面试:为什么要索引?什么是MySQL索引?底层结构是什么?

滴滴面试:单表可以存200亿数据吗?单表真的只能存2000W,为什么?

  • 索引下推 ?

贝壳面试:什么是回表?什么是 索引下推 ?

  • 索引失效

美团面试:mysql 索引失效?怎么解决?(重点知识,建议收藏,读10遍+)

  • MVCC

MVCC学习圣经:一文穿透MySQL MVCC,吊打面试官

  • binlog、redolog、undo log

美团面试:binlog、redolog、undo log底层原理是啥?分别实现ACID哪个特性?(尼恩图解,史上最全)

  • mysql 事务

阿里面试:事务ACID,底层是如何实现的?

京东面试:RR隔离mysql如何实现?什么情况RR不能解决幻读?

  • 分布式事务

分布式事务圣经:从入门到精通,架构师尼恩最新、最全详解 (50+图文4万字全面总结 )

阿里面试:秒杀的分布式事务, 是如何设计的?

  • mysql 调优

如何做mysql调优?绝命7招,让慢SQL调优100倍

说在最后:有问题找老架构取经‍

只要按照上面的 尼恩团队梳理的 方案去作答, 你的答案不是 100分,而是 120分。 面试官一定是 心满意足, 五体投地。

按照尼恩的梳理,进行 深度回答,可以充分展示一下大家雄厚的 “技术肌肉”,让面试官爱到 “不能自已、口水直流”,然后实现”offer直提”。

在面试之前,建议大家系统化的刷一波 5000页《尼恩Java面试宝典PDF》,里边有大量的大厂真题、面试难题、架构难题。

很多小伙伴刷完后, 吊打面试官, 大厂横着走。

在刷题过程中,如果有啥问题,大家可以来 找 40岁老架构师尼恩交流。

另外,如果没有面试机会, 可以找尼恩来改简历、做帮扶。前段时间,刚指导一个27岁 被裁小伙,拿到了一个年薪45W的JD +PDD offer,逆天改命。

狠狠卷,实现 “offer自由” 很容易的, 前段时间一个武汉的跟着尼恩卷了2年的小伙伴, 在极度严寒/痛苦被裁的环境下, offer拿到手软, 实现真正的 “offer自由” 。

尼恩技术圣经系列PDF

……完整版尼恩技术圣经PDF集群,请找尼恩领取

《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》PDF,请到下面公号【技术自由圈】取↓↓↓

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
缓存 NoSQL 关系型数据库
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
美团面试:MySQL有1000w数据,redis只存20w的数据,如何做 缓存 设计?
|
存储 关系型数据库 MySQL
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
阿里面试:MySQL 一个表最多 加几个索引? 6个?64个?还是多少?
|
关系型数据库 MySQL Java
字节面试: MySQL 百万级 导入发生的 “死锁” 难题如何解决?“2序4拆”,彻底攻克
字节面试: MySQL 百万级 导入发生的 “死锁” 难题如何解决?“2序4拆”,彻底攻克
字节面试: MySQL 百万级 导入发生的 “死锁” 难题如何解决?“2序4拆”,彻底攻克
|
SQL 存储 关系型数据库
美团面试:事务提交了,数据丢失 了 ?大概的原因是什么?
美团面试:事务提交了,数据丢失 了 ?大概的原因是什么?
美团面试:事务提交了,数据丢失 了 ?大概的原因是什么?
|
SQL 存储 关系型数据库
滴滴面试:明明 mysql 加的是 行锁,怎么就变 表锁 了?
滴滴面试:明明 mysql 加的是 行锁,怎么就变 表锁 了?
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
560 4
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
2853 2

推荐镜像

更多