当前位置: 首页 > news >正文

【面试】MySQL 面试常见优化问题

1. 为什么要建索引?索引一定能提高性能吗?

  • 场景:一个表有上千万数据,查询 SELECT * FROM user WHERE age=25;

  • 问题:没有索引时会全表扫描,性能差。

  • 解决方案

    • age 建立普通索引,加快查询。

    • 但是索引不是越多越好:

      • 插入、更新会更慢(需要维护索引)。

      • 索引在选择性差(如 gender 字段只有男女)时可能没效果。

2. 覆盖索引是什么?为什么快?

  • 场景:查询用户 ID 列表:

    SELECT id FROM user WHERE age = 25;
    
  • 说明:如果 age 上有索引,且查询只需要返回 id(在索引树中已包含),就不用回表。

  • 优化点:建组合索引 (age, id),查询时只走索引层,不访问数据页。

3. COUNT(*) 为什么慢?如何优化?

  • 场景:统计 order 表的总数,有上千万行。

  • 问题COUNT(*) 会逐行扫描统计。

  • 优化方法

    • 如果是估算:用 EXPLAINrows

    • 如果是精确计数:可以做 冗余表缓存(Redis)。

    • InnoDB 会遍历二级索引+主键,不像 MyISAM 有行数缓存。

4. SQL 执行慢的常见原因?

  • 场景:某个 SQL 在测试库很快,但生产库很慢。

  • 常见原因

    1. 没有走索引,发生全表扫描。

    2. 走了索引但选择性差,优化器放弃。

    3. 隐式转换(WHERE phone = 1380000,字段是 VARCHAR)。

    4. 统计信息不准。

  • 解决

    • 查看 EXPLAIN

    • 强制索引 FORCE INDEX

    • 优化字段类型,避免隐式转换。

    • 更新统计信息 ANALYZE TABLE user;

5. 什么时候建组合索引?最左匹配原则怎么理解?

  • 场景:经常有查询:

    SELECT * FROM user WHERE country = 'CN' AND age = 25;
    
  • 说明

    • 建组合索引 (country, age),比单列索引效率高。

    • 最左匹配:索引从最左边开始生效,(a,b,c) 等价于 (a)(a,b),但不会用 (b) 单独索引。

  • 优化点

    • 多条件查询,优先建组合索引。

    • 条件字段顺序,选择性高的放前面。

6. 如何优化分页查询?

  • 场景

    SELECT * FROM orders ORDER BY create_time LIMIT 100000, 20;
    

    很慢,因为 MySQL 先扫描10万行再丢弃。

  • 优化方法

    1. 记录上一次的偏移:

      SELECT * FROM orders WHERE id > 100000 LIMIT 20;
      
    2. 用覆盖索引 + join:

      SELECT o.* FROM orders o
      JOIN (SELECT id FROM orders ORDER BY id LIMIT 100000, 20) t
      ON o.id = t.id;
      

7. 为什么要分库分表?分库分表后怎么查?

  • 场景user 表超过 1 亿行,查询、写入都慢。

  • 优化思路

    • 分库分表:按 user_id % 8 拆成 8 张表。

    • 查询时通过中间件(ShardingSphere、Mycat)路由。

    • 跨库统计问题 → 用 中间件聚合异步汇总表

8. InnoDB 和 MyISAM 的区别?为什么选择 InnoDB?

  • 场景:设计电商订单表。

  • 区别

    • InnoDB:支持事务、行锁、MVCC,适合高并发。

    • MyISAM:表锁、无事务、计数快,适合只读场景。

  • 面试要点:几乎所有业务型系统用 InnoDB,因为数据安全更重要。

9. 大表优化思路?

  • 场景:订单表 5 亿行,查询和维护很慢。

  • 优化点

    1. 水平拆分(分库分表)。

    2. 冷热数据分离:历史数据归档。

    3. 索引优化:只建必要索引。

    4. 读写分离:主库写,从库读。

    5. 缓存:Redis 缓存热点数据。

10. 如何排查慢查询?

  • 步骤

    1. 打开慢查询日志:

      slow_query_log = ON
      long_query_time = 1
      
    2. EXPLAIN 分析执行计划。

    3. 观察是否用到索引、rows 预估数。

    4. SHOW PROFILE 查看耗时阶段。

    5. 实在不行,用 pt-query-digest 工具分析日志。

http://www.dtcms.com/a/366841.html

相关文章:

  • 面试官:如何确保动态线程池任务都执行完?
  • 计算机网络模型入门指南:分层原理与各层作用
  • EasyExcel:阿里开源的高效 Excel 处理工具,轻松解决 POI 内存溢出问题
  • SolidWorks对电脑的硬件配置要求具体有哪些
  • [Sublime Text]-显示菜单栏
  • 《云原生深坑实录:让团队卡壳的不是配置,是底层逻辑盲区》
  • 【Dify】使用工具节点实现 API 接口调用与 JSON 处理
  • 25高教社杯数模国赛【B题超高质量思路+问题分析】
  • 具身智能多模态感知与场景理解:视觉探索
  • 第二阶段WinForm-13:图表控件,N层架构,Dapper
  • 数据结构与排序算法:从理论到场景,解锁高效数据处理的核心逻辑
  • 【项目思路】基于STM32+ZigBee的智能家居--浴室场景设计
  • 服务器异常负载排查手册 · 隐蔽进程篇
  • QT面经(含相关知识)
  • elasticsearch学习(五)文档CRUD
  • 前端跨域终极指南:3 种优雅解决方案 + 可运行 Demo
  • App UI 自动化环境搭建指南
  • Java Stream 流式操作举例
  • QT Creator 使用
  • 【一文了解】C#泛型
  • 数据库集成:使用 SQLite 与 Electron
  • 新电脑硬盘如何分区?3个必知技巧避免“空间浪费症”!
  • [技术革命]Harmonizer:仅20MB模型如何实现8K图像_视频的完美和谐化?
  • 鸿蒙:AppStorageV2状态管理和数据共享
  • 泛型的通配符
  • axios请求缓存与重复拦截:“相同请求未完成时,不发起新请求”
  • TDengine TIMETRUNCATE 函数用户使用手册
  • 野火STM32Modbus主机读取寄存器/线圈失败(三)-尝试将存贮事件的地方改成数组(非必要解决方案)(附源码)
  • 腾讯云国际代理:如何在腾讯云GPU服务器上部署私有化大模型?附GPU简介
  • SQLmap 完整使用指南:环境搭建 + 命令详解 + 实操案例