美团面试:Mysql如何选择最优 执行计划,为什么?

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 在40岁老架构师尼恩的读者交流群中,近期有小伙伴面试美团时遇到了关于MySQL执行计划的面试题:“MySQL如何选择最优执行计划,为什么?”由于缺乏系统化的准备,小伙伴未能给出满意的答案,面试失败。为此,尼恩为大家系统化地梳理了MySQL执行计划的相关知识,帮助大家提升技术水平,展示“技术肌肉”,让面试官“爱到不能自已”。相关内容已收录进《尼恩Java面试宝典PDF》V175版本,供大家参考学习。

尼恩说在前面

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

Mysql如何选择最优 执行计划,为什么?

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

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

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

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

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

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

一、什么是执行计划(MySQL Execution Plan)?

MySQL Execution Plan (执行计划)是 MySQL 数据库在处理查询语句时,确定的一套具体操作步骤。

MySQL Execution Plan (执行计划) 描述了数据库引擎如何访问表、如何 使用索引,以及以何种顺序执行连接和过滤操作等内容。

对于复杂的查询,不同的执行计划可能会导致查询性能有天壤之别。

一个高效的执行计划能够充分利用索引,减少数据的读取量和磁盘 I/O 操作,从而快速地返回查询结果。

二、MySQL 优化器的作用

MySQL 有一个查询优化器,它的主要任务是在众多可能的执行计划中选择一个最优的计划。

再 介绍查询优化器 之前, 我们看看 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的结构生成不同的执行计划, 是MySQL优化器 的主要任务。

  • 在众多可能的执行计划中选择一个最优的计划, 这是MySQL执行器 的主要任务。

    执行器最终选择最优或者执行效率最高的执行计划, 执行sql并返回数据。

四、影响执行计划选择的因素

那么这个最优的执行计划是如何选择的呢?

优化器会考虑多种因素,如每个执行计划的成本、索引的可用性、表的大小、数据分布情况、连接条件等。

因素1:每个执行计划的成本

优化器会估算每个执行计划的成本。成本主要包括 I/O 成本(从磁盘读取数据的开销)和 CPU 成本(对数据进行处理的开销)。

例如,使用索引进行查询可能会减少 I/O 成本,但如果索引需要大量的 CPU 资源来维护或者遍历,那么优化器会综合考虑这两种成本来决定是否使用该索引。

因素2:索引是否存在?

当查询语句中的列有合适的索引时,优化器会考虑使用索引来加速查询。例如,对于一个SELECT * FROM users WHERE user_id = 123的查询,如果user_id列有索引,优化器可能会选择使用索引来定位满足条件的行,而不是全表扫描。

因素3:复合索引的是否能最左匹配?

对于复合索引(包含多个列的索引),列的顺序也很重要。

例如,有一个复合索引(col1, col2, col3),如果查询条件是col1 = 'value1' AND col2 = 'value2',那么这个复合索引可以被有效地利用。

但如果查询条件是col2 = 'value2' AND col3 = 'value3',索引的使用效率可能会降低,优化器可能需要重新评估是否使用该索引。

因素4:连接类型和顺序?

不同的连接类型(如内连接、外连接、交叉连接等)会影响执行计划。例如,内连接是比较常用的连接方式,它只返回满足连接条件的行。优化器会根据连接条件和表的大小来确定连接的顺序。一般来说,会先选择较小的表作为驱动表,这样可以减少连接操作的成本。

在多表连接的情况下,连接顺序的不同组合会产生多种执行计划。例如,对于三个表ABC的连接,可能的连接顺序有((A JOIN B) JOIN C)((A JOIN C) JOIN B)((B JOIN C) JOIN A)等,优化器会通过计算成本来选择最优的连接顺序。

因素5:连接条件的选择性?

连接条件的选择性是指连接条件能够过滤掉多少行。如果连接条件的选择性很高,例如A.col1 = B.col1,并且col1列的值在两个表中都比较唯一,那么优化器可能会更倾向于使用这种连接条件来减少连接操作后的结果集大小。

因素6:数据分布情况?

如果列的数据分布不均匀,例如一个列大部分值都相同,只有少数几个不同的值,那么索引在这种情况下的作用可能会受到限制。优化器会考虑这种数据分布情况来决定是否使用索引以及如何使用索引。

其他的考察因素:如表的数据量和增长趋势

表的数据量大小直接影响查询的性能。对于大数据量的表,优化器会更倾向于寻找能够减少数据读取量的执行计划。

同时,表的增长趋势也很重要。如果一个表的数据量在不断增加,那么优化器可能需要重新评估现有的执行计划是否仍然是最优的。

五、通过EXPLAIN 查看每个执行计划的成本

使用EXPLAIN命令查看和分析执行计划。EXPLAIN是 MySQL 提供的一个用于查看查询执行计划的工具。

在查询语句前加上EXPLAIN关键字,MySQL 会返回一个结果集,其中包含了执行计划的详细信息。例如:

EXPLAIN SELECT * FROM users JOIN orders ON users.user_id = orders.user_id;

这个EXPLAIN结果会显示表的连接方式、使用的索引(如果有)、扫描的行数等信息。

通过分析这些信息,可以了解 MySQL 是如何执行这个查询的,以及是否存在优化的空间。

理解EXPLAIN结果中的关键列

  • id列:表示查询中每个 SELECT 子句的标识符。如果是简单的单表查询,id通常为 1。在复杂的子查询或连接查询中,id可以帮助区分不同的子查询或连接部分。
  • select_type列:描述了查询的类型,如SIMPLE(简单查询)、PRIMARY(主查询)、SUBQUERY(子查询)等。不同的查询类型可能会有不同的执行计划。
  • table列:显示查询涉及的表的名称。
  • type列:表示表的访问类型,这是评估执行计划效率的一个重要指标。常见的访问类型有ALL(全表扫描)、index(索引扫描)、range(范围扫描)、ref(非唯一索引扫描)、eq_ref(唯一索引扫描)等。一般来说,eq_refref的效率较高,而ALL效率较低。
  • possible_keys列:显示查询可能使用的索引。这只是一个参考,优化器可能会根据实际情况选择不使用其中的某些索引。
  • key列:实际使用的索引。如果这个列显示为NULL,表示没有使用索引,可能是因为优化器认为使用索引的成本更高或者没有合适的索引。
  • key_len列:表示使用的索引的长度。这个长度可以帮助判断索引是否被充分利用。例如,对于一个复合索引,如果key_len只覆盖了索引的一部分列,可能表示索引没有被完全利用。
  • ref列:显示索引的引用情况。如果是通过索引进行连接操作,这个列会显示连接所引用的列。
  • rows列:估算的需要扫描的行数。这个数字越小,通常表示执行计划越高效。
  • Extra列:包含了一些额外的信息,如是否使用了临时表、是否使用了文件排序等。这些信息可以帮助发现潜在的性能问题。

在 MySQL 中,EXPLAIN命令用于获取查询的执行计划信息,FORMAT参数可以指定输出的格式。

以下是一些常见的格式及说明:

  1. TRADITIONAL(默认格式):

    以传统的表格形式展示执行计划信息,包括idselect_typetabletypepossible_keyskeykey_lenrefrowsExtra等列。每一列都代表了执行计划的不同方面,例如:

  2. JSON

    以 JSON 格式输出执行计划信息,更易于解析和处理,尤其是在需要进行自动化分析或与其他工具集成时。

    JSON 格式的输出包含了更多详细的信息,如成本估算、访问路径等。

六 实操:通过执行计划查看每个执行计划的成本

添加测试数据:首先创建一张测试表 test_user表, 造50W数据

创建一张user表,表中包含:idid_cardageuser_nameheight、address字段。

CREATE TABLE `test_user` (
`id` int NOT NULL AUTO_INCREMENT, 
`id_card` varchar(20) COLLATE utf8mb4_bin DEFAULT NULL, 
`age` int DEFAULT '0', 
`user_name` varchar(30) COLLATE utf8mb4_bin DEFAULT NULL,
`height` int DEFAULT '0',  
`address` varchar(30) COLLATE utf8mb4_bin DEFAULT NULL,  
PRIMARY KEY (`id`), 
KEY `idx_id_card_age_user_name` (`id_card`,`age`,`user_name`), 
KEY `idx_height` (`height`))
ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

使用存储过程,插入50W条测试数据, 具体请参见尼恩的前面文章

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

(1)使用二级索引的执行计划 和执行成本

执行sql如下所示:

EXPLAIN FORMAT=JSON SELECT * from `test_user`   where height = 120;

sql的执行结果如下所示:

{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "7252.80"
    },
    "table": {
      "table_name": "test_user",
      "access_type": "ref",
      "possible_keys": [
        "idx_height"
      ],
      "key": "idx_height",
      "used_key_parts": [
        "height"
      ],
      "key_length": "5",
      "ref": [
        "const"
      ],
      "rows_examined_per_scan": 6044,
      "rows_produced_per_join": 6044,
      "filtered": "100.00",
      "cost_info": {
        "read_cost": "6044.00",
        "eval_cost": "1208.80",
        "prefix_cost": "7252.80",
        "data_read_per_join": "1M"
      },
      "used_columns": [
        "id",
        "id_card",
        "age",
        "user_name",
        "height",
        "address"
      ]
    }
  }
}

执行结果中的cost=7252.80,Mysql认为我们当前的sql执行的成本是7252.80。

这个命令是在 MySQL 中使用 EXPLAIN 以 JSON 格式输出 SELECT * fromtest_userIGNORE index(idx_height) where height = 120; 查询的执行计划信息。

以下是对这个命令及输出的分析:

一、命令解释

  1. EXPLAIN:用于获取 SQL 查询的执行计划信息,帮助了解 MySQL 如何执行该查询。
  2. FORMAT=JSON:指定输出格式为 JSON,这种格式可以更清晰地展示执行计划的各个方面,并且方便解析和处理。
  3. SELECT * fromtest_userIGNORE index(idx_height) where height = 120;:这是一个查询语句,从名为 test_user 的表中选择所有列的数据,条件是 height = 120,并且明确忽略名为 idx_height 的索引。

二、可能的输出内容及含义

以下是对给定 JSON 格式的执行计划结果的详细解释:

  1. "query_block":

    • 代表查询块信息,描述了整个查询的执行计划相关内容。
  2. "select_id": 1

    • 查询的唯一标识符为 1。
  3. "cost_info":

    • "query_cost": "7252.80": 查询的预估总成本为 7252.80。这个成本是 MySQL 优化器根据多种因素估算出来的,包括读取数据的成本、评估条件的成本等。一般来说,成本越低,查询的执行效率可能越高。
  4. "table":

    • "table_name": "test_user": 查询涉及的表名为 test_user

    • "access_type": "ref": 访问类型为 ref,表示通过非唯一索引进行查找。在这个例子中,说明查询使用了索引进行查找,并且不是唯一索引。

    • "possible_keys": ["idx_height"]: 可能使用的索引列表为 idx_height,这表明优化器考虑了这个索引,并最终选择了它。

    • "key": "idx_height": 实际使用的索引是 idx_height,说明优化器认为使用这个索引可以提高查询性能。

    • "used_key_parts": ["height"]: 使用的索引部分是 height 列,表明索引 idx_height 是基于 height 列创建的,并且在查询中只使用了这个索引的 height 部分。

    • "key_length": "5": 索引的长度为 5,可能与存储 height 列的值所需的空间有关。

    • "ref": ["const"]: 索引引用的值是常量,这里可能是查询条件中的 height = 120 中的 120。

    • "rows_examined_per_scan": 6044: 每次扫描检查的行数为 6044。这表示在执行查询过程中,需要检查的行数估计为 6044 行。

    • "rows_produced_per_join": 6044: 每次连接产生的行数为 6044。如果查询涉及多个表的连接,这个值表示从这个表中产生的行数,用于连接操作。

    • "filtered": "100.00": 过滤后的行数比例为 100%。这意味着经过查询条件 height = 120 过滤后,所有满足条件的行数占总检查行数的比例为 100%。

    • "cost_info":

      • "read_cost": "6044.00": 读取数据的成本为 6044.00。
      • "eval_cost": "1208.80": 评估条件的成本为 1208.80。
        • "prefix_cost": "7252.80": 前缀成本为 7252.80,通常是指查询的总成本减去某些特定操作的成本。
    • "data_read_per_join": "1M": 每次连接读取的数据量为 1M(可能是 1 兆字节)。

    • "used_columns": ["id", "id_card", "age", "user_name", "height", "address"]: 查询使用的列包括 idid_cardageuser_nameheightaddress。这意味着查询将从表中读取这些列的数据。

(2)执行成本的介绍

  1. 执行成本的单位
    • MySQL 优化器的成本单位是一个相对的抽象概念,没有一个具体的物理单位(如秒、字节等)与之对应。它是一个综合衡量指标,用于比较不同执行计划的资源消耗情况。成本主要由 I/O 成本(从磁盘读取数据的开销)和 CPU 成本(对数据进行处理的开销)组成。
  2. I/O 成本
    • I/O 成本通常与磁盘读取操作相关。在 MySQL 中,读取一个数据页(一般是 16KB)的 I/O 成本默认被估算为 1.0。例如,若一个执行计划需要读取 10 个数据页,那么其 I/O 成本估算值可能为 10.0 左右。这个值会根据存储引擎的不同特性以及系统的硬件配置等因素有所变化。
    • 对于 InnoDB 存储引擎,它有自己的缓冲池(Buffer Pool)。如果数据已经在缓冲池中,那么读取这些数据的 I/O 成本会相对较低,因为不需要从磁盘进行物理读取。优化器在计算成本时会考虑数据在缓冲池中的可能性,这是基于缓冲池的命中率等因素来估算的。
  3. CPU 成本
    • CPU 成本涉及到对数据的处理操作,如比较、排序、函数计算等。例如,在进行索引查找时,需要在索引结构中进行比较操作,这会产生 CPU 成本。CPU 成本的估算相对复杂,它取决于操作的类型和数据量等因素。
    • 对于一个简单的比较操作(如判断一个列的值是否等于某个常量),其 CPU 成本相对较低;而对于复杂的操作,如对大量数据进行排序或者使用复杂的函数进行数据转换,CPU 成本会较高。在计算成本时,优化器会根据操作的复杂度和涉及的数据量来估算 CPU 成本。
  4. 成本的综合计算与比较
    • 优化器在计算总成本时,会将 I/O 成本和 CPU 成本相加。例如,一个执行计划的 I/O 成本估算为 5.0,CPU 成本估算为 3.0,那么总成本就是 8.0。优化器会比较不同执行计划的总成本,选择成本最低的执行计划来执行查询。
    • 不过,成本估算只是一个参考,实际的性能还可能受到硬件性能(如磁盘 I/O 速度、CPU 速度)、系统负载、数据分布等因素的影响。有时候,优化器选择的成本最低的执行计划在实际运行中可能并不是最优的,这就需要通过性能测试和调优等手段来进一步优化查询。

(3)禁用二级索引后的执行计划 和执行成本

执行忽略二级索引的sql如下所示:

执行sql如下所示:

EXPLAIN FORMAT=JSON SELECT * from `test_user`  IGNORE index(idx_height) where height = 120;

在 SQL 语句中,“IGNORE INDEX (index_name)” 的作用是在执行查询时忽略指定的索引。

这里明确告诉数据库在执行这个查询时不要使用名为 “idx_height” 的索引,即使该索引可能与查询条件中的 “height” 列相关。

IGNORE INDEX 关键词的 几个使用场景:

  1. 性能调试:有时候开发人员可能怀疑某个索引没有被正确使用或者正在尝试不同的查询执行计划,通过忽略特定索引可以观察查询在没有该索引时的性能表现,从而更好地理解数据库的执行计划和索引的实际影响。
  2. 解决索引冲突:如果某个索引的存在导致了查询执行计划的问题,比如产生了错误的连接顺序或者不必要的索引扫描,通过忽略该索引可以强制数据库使用其他可能更优的执行方式。
  3. 特殊需求:在某些特定的业务场景下,可能根据具体的查询需求故意不使用某个索引,以满足特定的性能或数据一致性要求。

架构师尼恩提示: 上面的例子,就是对应到场景3.

架构师尼恩提示:谨慎使用 “IGNORE INDEX”,因为在大多数情况下,数据库的优化器会根据统计信息和各种因素自动选择最合适的索引来提高查询性能。如果随意忽略索引,可能会导致查询性能下降。

禁用二级索引后的 , sql的执行结果如下所示:

{
  "query_block": {
    "select_id": 1,
    "cost_info": {
      "query_cost": "100134.80"
    },
    "table": {
      "table_name": "test_user",
      "access_type": "ALL",
      "rows_examined_per_scan": 489294,
      "rows_produced_per_join": 5966,
      "filtered": "1.22",
      "cost_info": {
        "read_cost": "98941.40",
        "eval_cost": "1193.40",
        "prefix_cost": "100134.80",
        "data_read_per_join": "1M"
      },
      "used_columns": [
        "id",
        "id_card",
        "age",
        "user_name",
        "height",
        "address"
      ],
      "attached_condition": "(`store`.`test_user`.`height` = 120)"
    }
  }
}

执行结果中的cost=100134.80,Mysql认为我们当前的sql执行的成本是100134.80。

以下是对这个命令及输出的分析:

JSON 格式的输出通常包含多个字段,以下是一些常见字段的解释:

  1. "query_block":
    • "select_id": 查询的标识符。
    • "cost_info":
      • "query_cost": 查询的总成本估计。这是一个综合考虑了 I/O 成本和 CPU 成本的数值,值越小通常表示执行计划越高效。
  2. "table":
    • "name": 表的名称,这里是 test_user
    • "access_type": 访问表的方式,可能的值有 ALL(全表扫描)、index(索引扫描)、range(范围扫描)等。如果忽略了索引,可能会出现全表扫描,即 access_typeALL
    • "possible_keys": 该查询可能使用的索引列表。由于使用了 IGNORE index(idx_height),所以这里不会显示 idx_height
    • "key": 实际使用的索引,如果没有使用任何索引,该值为 NULL
    • "rows": 预估需要扫描的行数。
    • "filtered": 表示经过筛选条件过滤后剩余行数的比例。

通过分析这个 JSON 格式的执行计划输出,可以了解 MySQL 在执行这个查询时的具体策略,判断是否存在性能问题,并考虑是否需要调整查询语句、创建新的索引或者优化表结构等,以提高查询性能。

两条执行计划的对比

可以生成两条执行计划,一个是走索引(idx_height)的执行计划,另一个是全表扫描的执行计划,并且通过sql分析我们发现两者的cost值不一样的,cost的值如下所示:

执行方式 cost
索引执行计划 7252.80
全表扫面执行计划 100134.80

然后Mysql就选择cost最小的执行计划来执行我们的sql。

五、优化执行计划的方法

  1. 优化索引

    根据查询语句的需求,创建合适的索引。对于频繁用于查询条件、连接条件和排序的列,应该考虑创建索引。但要注意避免创建过多的索引,因为索引本身也会占用磁盘空间,并且在插入、更新和删除数据时需要维护索引,会增加额外的开销。

  1. 调整查询语句

    优化查询语句的写法可以影响执行计划。

    如,尽量避免在查询条件中使用函数或者表达式,因为这可能会导致索引无法使用。

    比如,SELECT * FROM users WHERE YEAR(birth_date) = 1990,这个查询中的YEAR()函数会使得birth_date列的索引无法使用。

    可以将查询改写为SELECT * FROM users WHERE birth_date BETWEEN '1990 - 01 - 01' AND '1990 - 12 - 31',这样就有可能使用索引了。

  1. 优化表结构

    合理的表结构设计也有助于优化执行计划。

    例如,将经常一起查询的列放在同一个表或者同一个列族(如果是基于列存储的数据库)中,可以减少数据的读取量。

    对于大数据量的表,可以考虑进行垂直或水平拆分,以提高查询性能。

关于mysql 执行计划的调优,还可以看看下面的文章:

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

MySQL 选择最优执行计划是一个复杂的过程,涉及到数据库的内部机制、数据特征和查询需求等多个方面。

通过深入了解执行计划的选择原理,合理利用工具查看和分析执行计划,并采取有效的优化措施,可以提高 MySQL 查询的性能,更好地满足应用程序的需求。

尼恩架构团队的塔尖 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,请到下面公号【技术自由圈】取↓↓↓

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
15天前
|
SQL 关系型数据库 MySQL
大厂面试官:聊下 MySQL 慢查询优化、索引优化?
MySQL慢查询优化、索引优化,是必知必备,大厂面试高频,本文深入详解,建议收藏。关注【mikechen的互联网架构】,10年+BAT架构经验分享。
大厂面试官:聊下 MySQL 慢查询优化、索引优化?
|
1月前
|
缓存 关系型数据库 MySQL
MySQL执行计划选择策略:揭秘查询优化的艺术
【10月更文挑战第15天】 在数据库性能优化中,选择最优的执行计划是提升查询效率的关键。MySQL作为一个强大的关系型数据库管理系统,提供了复杂的查询优化器来生成执行计划。本文将深入探讨如何选择合适的执行计划,以及为什么某些计划更优。
63 2
|
29天前
|
SQL 缓存 关系型数据库
美团面试:Mysql 有几级缓存? 每一级缓存,具体是什么?
在40岁老架构师尼恩的读者交流群中,近期有小伙伴因未能系统梳理MySQL缓存机制而在美团面试中失利。为此,尼恩对MySQL的缓存机制进行了系统化梳理,包括一级缓存(InnoDB缓存)和二级缓存(查询缓存)。同时,他还将这些知识点整理进《尼恩Java面试宝典PDF》V175版本,帮助大家提升技术水平,顺利通过面试。更多技术资料请关注公号【技术自由圈】。
美团面试:Mysql 有几级缓存? 每一级缓存,具体是什么?
|
23天前
|
SQL 算法 关系型数据库
面试:什么是死锁,如何避免或解决死锁;MySQL中的死锁现象,MySQL死锁如何解决
面试:什么是死锁,死锁产生的四个必要条件,如何避免或解决死锁;数据库锁,锁分类,控制事务;MySQL中的死锁现象,MySQL死锁如何解决
|
1月前
|
缓存 关系型数据库 MySQL
MySQL执行计划深度解析:如何做出最优选择
【10月更文挑战第23天】 在数据库查询性能优化中,执行计划的选择至关重要。MySQL通过查询优化器来生成执行计划,但有时不同的执行计划会导致性能差异。理解如何选择合适的执行计划,以及为什么某些计划更优,对于数据库管理员和开发者来说是一项必备技能。
50 2
|
4月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
20天前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
21天前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
43 4
|
2月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
78 2
|
2月前
|
JSON 安全 前端开发
第二次面试总结 - 宏汉科技 - Java后端开发
本文是作者对宏汉科技Java后端开发岗位的第二次面试总结,面试结果不理想,主要原因是Java基础知识掌握不牢固,文章详细列出了面试中被问到的技术问题及答案,包括字符串相关函数、抽象类与接口的区别、Java创建线程池的方式、回调函数、函数式接口、反射以及Java中的集合等。
31 0