MySQL面试01

MySQL 索引的最左原则

🍰 最左原则本质

=͟͟͞͞( •̀д•́) 想象复合索引是电话号码簿!

索引 (a,b,c) 的排列顺序:

先按a排序 → a相同按b排序 → 最后按c排序

生效场景三连:

1️⃣ WHERE a=1

2️⃣ WHERE a=1 AND b=2

3️⃣ WHERE a=1 AND b=2 AND c=3

💣 失效场景三连:

1️⃣ WHERE b=2 ❌ (跳过了a)

2️⃣ WHERE a=1 AND c=3 ❌ (中间断了b)

3️⃣ WHERE b=2 AND c=3 ❌ (首列失踪)

特殊技巧:

  • WHERE a>1 AND b=2 → 只有a能用索引(范围查询后断链)
  • WHERE a=1 ORDER BY b,c → 排序也能用索引!
  • WHERE a LIKE '张%' ✅ (前缀匹配)
复制代码

哦呜(°ロ°)!曼波举个栗子:

索引是(班级, 姓名, 年龄)

✅ 查"3班 张三" → 直接翻到3班区域找张三

❌ 直接查"年龄18" → 要扫描全校学生

InnoDB 和 Mylsam 引擎的区别?

这两个引擎的区别就像奶茶和咖啡的选择,要根据场景来pick哦!

🍵 MyISAM (经典奶茶型)

=͟͟͞͞( •̀д•́) 适合读多写少的场景!

  • 不支持事务(像现金交易,要么成功要么失败)
  • 表级锁(修改时要锁整个表)
  • 存储结构:
    .MYD数据文件 + .MYI索引文件(像分开的奶茶和珍珠)
  • 特色技能:
    ✅ 全文索引
    ✅ COUNT(*) 超快(自带计数器)
    ❌ 崩溃后容易数据损坏

InnoDB (现代咖啡机型)

(๑•̀ㅂ•́)و✧ 适合高并发事务场景!

  • 支持ACID事务(像电子支付可回滚)
  • 行级锁(只锁修改的行)
  • 存储结构:
    聚簇索引(数据&索引存在一起像浓缩咖啡)
  • 特色技能:
    ✅ 外键约束
    ✅ 崩溃自动恢复(redo log像咖啡机自动清洁)
    ✅ MVCC多版本并发控制
复制代码

📊 性能对比小剧场:

  • 全表COUNT:MyISAM 🚀(秒出结果) vs InnoDB 🐢(要扫描)
  • 并发写入:MyISAM 😵(表锁阻塞) vs InnoDB 😎(行锁流畅)
  • 数据安全:MyISAM 🚑(需定期修复) vs InnoDB 🛡️(自动恢复)

(✪▽✪)曼波~~ 现在主流都用InnoDB啦~就像大家现在更爱喝手冲咖啡!除非特殊需求(比如全文检索),否则推荐默认选InnoDB哦!

有哪些优化数据库性能的方法?

一、💡 SQL 优化三板斧

1. EXPLAIN 大法

sql 复制代码
EXPLAIN SELECT * FROM users WHERE age > 25 ORDER BY create_time;
-- 重点观察:type(扫描类型)、key(使用索引)、rows(扫描行数)

2. 索引优化技巧

  • 给WHERE/ORDER BY/JOIN字段加索引
  • 避免在索引列上做计算:WHERE YEAR(create_time)=2023
  • 使用覆盖索引:SELECT 索引字段

3. 慢查询日志分析

sql 复制代码
# my.cnf 配置
slow_query_log = 1
long_query_time = 1  # 超过1秒的查询

mysqldumpslow工具分析日志


二、🚀 结构设计优化

1. 三范式与反范式的平衡

  • 适度冗余:减少JOIN次数
  • 大字段分离:把TEXT/BLOB单独存表

2. 分区表实战

sql 复制代码
-- 按时间范围分区
CREATE TABLE logs (
    id INT,
    log_time DATETIME
) PARTITION BY RANGE (YEAR(log_time)) (
    PARTITION p2022 VALUES LESS THAN (2023),
    PARTITION p2023 VALUES LESS THAN (2024)
);

3. 冷热数据分离

  • 热数据:最近3个月订单 → SSD存储
  • 冷数据:历史订单 → HDD归档

三、⚙️ 配置调优示例

InnoDB 核心参数

sql 复制代码
innodb_buffer_pool_size = 70%内存  # 缓存池大小
innodb_flush_log_at_trx_commit = 2  # 平衡安全与性能
max_connections = 1000  # 根据实际调整

四、🛠️ 架构级优化

1. 读写分离

  • 主库处理写操作
  • 从库处理读查询

2. 缓存策略

java 复制代码
import redis.clients.jedis.Jedis;

public class UserService {
    private static final String REDIS_HOST = "localhost";
    private static final int REDIS_PORT = 6379;
    
    // 曼波小贴士:真实项目要用连接池哦!
    public User getUser(String userId) {
        try (Jedis jedis = new Jedis(REDIS_HOST, REDIS_PORT)) {
            // 1. 先查缓存
            String redisKey = "user:" + userId;
            String cachedData = jedis.get(redisKey);
            
            if (cachedData != null) {
                return JSON.parseObject(cachedData, User.class); // 使用JSON库反序列化
            }
            
            // 2. 缓存未命中则查数据库
            User user = jdbcTemplate.queryForObject(
                "SELECT * FROM users WHERE id = ?", 
                new Object[]{userId}, 
                new UserRowMapper()
            );
            
            // 3. 写入缓存(设置1小时过期)
            if (user != null) {
                jedis.setex(redisKey, 3600, JSON.toJSONString(user));
            }
            return user;
        }
    }
}

3. 分库分表

  • 垂直分库:用户库、订单库分离
  • 水平分表:user_001, user_002...

复制代码

(✪▽✪)曼波~~ 记住优化要像中医把脉,先诊断(分析慢查询)再开方(针对性优化)!

如何定位慢查询?

一、🔍 基础定位三板斧

1. 慢查询日志捕获

sql 复制代码
-- 临时开启(重启失效)
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;  -- 超过1秒的查询
SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';

-- 永久生效配置(my.cnf)
[mysqld]
slow_query_log = 1
long_query_time = 1
log_queries_not_using_indexes = 1  -- 记录未走索引的查询

2. 日志分析神器

bash 复制代码
# 查看最耗时的10个慢查询
mysqldumpslow -s t -t 10 /var/log/mysql/slow.log

# 解析结果示例
Count: 5  Time=3.21s (16s)  Lock=0.00s (0s)  Rows=1000.0 (5000)
  SELECT * FROM orders WHERE user_id=N

3. 实时监控SHOW PROCESSLIST

sql 复制代码
-- 查看正在运行的查询
SHOW FULL PROCESSLIST;

-- 重点关注:
State: "Sending data"      -- 正在传输数据
Time: 大于100秒的查询       -- 可能卡住的查询

二、🔧 深度分析工具包

1. EXPLAIN 执行计划解读

sql 复制代码
EXPLAIN FORMAT=JSON 
SELECT * FROM products 
WHERE category='electronics' 
ORDER BY price DESC;

-- 关键指标:
"access_type": "ALL"        -- 全表扫描(危险!)
"rows_examined_per_scan": 10000  -- 扫描行数
"using_filesort": true      -- 文件排序(需优化)
复制代码

2. Performance Schema 监控

sql 复制代码
-- 开启性能监控
UPDATE performance_schema.setup_instruments 
SET ENABLED = 'YES' 
WHERE NAME LIKE '%statement/%';

-- 查询TOP SQL
SELECT DIGEST_TEXT, AVG_TIMER_WAIT 
FROM performance_schema.events_statements_summary_by_digest 
ORDER BY AVG_TIMER_WAIT DESC 
LIMIT 10;
复制代码

3. pt-query-digest 高级分析

bash 复制代码
# 使用Percona Toolkit
pt-query-digest /var/log/mysql/slow.log

-- 输出包括:
# Rank 响应时间占比
# Attribute 各SQL指纹
# Exec time 执行时间统计
复制代码

三、🚀 Java生态专用方案

1. Druid 连接池监控

java 复制代码
// Spring Boot配置
@Bean
public ServletRegistrationBean<StatViewServlet> druidServlet() {
    return new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
}

// 监控指标包括:
- SQL执行时间排行
- 慢SQL记录(支持配置阈值)
- 执行次数TOP SQL
复制代码

2. MyBatis 打印慢SQL

XML 复制代码
<!-- mybatis-config.xml -->
<settings>
    <setting name="defaultStatementTimeout" value="5"/> <!-- 超时5秒 -->
</settings>

<!-- 配合p6spy记录真实SQL -->
driverClassName=com.p6spy.engine.spy.P6SpyDriver

复制代码
复制代码

(✪▽✪)曼波~~ 定位到慢SQL后,记得用「EXPLAIN+SQL重写+索引优化」三连击哦!

相关推荐
WeiLai1112几秒前
面试基础--MySQL SQL 优化深度解析
java·后端·sql·mysql·面试·架构
m0_742566602 分钟前
Mysql下载安装
数据库·mysql
北顾南栀倾寒3 分钟前
[杂学笔记]HTTP1.0和HTTP1.1区别、socket系列接口与TCP协议、传输长数据的时候考虑网络问题、慢查询如何优化、C++的垃圾回收机制
网络·c++·笔记·tcp/ip·mysql·http
搞不懂语言的程序员37 分钟前
数据库事务的 ACID,通过MVCC能做什么
java·开发语言·数据库
爱老的虎油39 分钟前
MySQL零基础教程16—表连接进阶
数据库·mysql
java—大象44 分钟前
基于SpringBoot+mybatis+layui就业管理系统设计和实现
java·数据库·spring boot·后端·layui·mybatis
m0_748233641 小时前
MySQL的底层原理与架构
数据库·mysql·架构
CodeJourney.1 小时前
DeepSeek赋能Power BI:开启智能化数据分析新时代
数据库·人工智能·算法
迅~2 小时前
Linux·数据库INSERT优化
数据库
Stark、2 小时前
【MySQL数据库】SQL语法基础--DQL(入门级)
数据库·sql·mysql