文章目录
- 前言
-
- [一、MySQL 核心特性与版本对比](#一、MySQL 核心特性与版本对比)
-
- [1. 核心技术特性](#1. 核心技术特性)
- [2. 主流版本对比(选型指南)](#2. 主流版本对比(选型指南))
- [二、MySQL 基础入门(安装+连接+基础操作)](#二、MySQL 基础入门(安装+连接+基础操作))
-
- [1. 安装与部署(3种方案)](#1. 安装与部署(3种方案))
-
- (1)本地安装(Windows/macOS/Linux)
- [(2)Docker 部署(快速便捷,推荐)](#(2)Docker 部署(快速便捷,推荐))
- (3)云数据库(生产环境首选)
- [2. 连接 MySQL(4种方式)](#2. 连接 MySQL(4种方式))
- [3. 数据库与表基础操作(SQL 命令)](#3. 数据库与表基础操作(SQL 命令))
-
- (1)数据库操作
- (2)表操作(DDL)
-
- [① 创建表(以用户表为例)](#① 创建表(以用户表为例))
- [② 表结构操作](#② 表结构操作)
- (3)数据操作(DML)
- (4)数据查询(DQL)
-
- [① 基础查询](#① 基础查询)
- [② 聚合查询(GROUP BY + 聚合函数)](#② 聚合查询(GROUP BY + 聚合函数))
- [③ 联表查询(多表关联)](#③ 联表查询(多表关联))
- [三、MySQL 核心高级功能(生产环境必备)](#三、MySQL 核心高级功能(生产环境必备))
-
- [1. 索引优化(性能核心)](#1. 索引优化(性能核心))
- [2. 事务管理(ACID 保障)](#2. 事务管理(ACID 保障))
- [3. 存储过程与触发器](#3. 存储过程与触发器)
-
- (1)存储过程(数据库端业务逻辑封装)
-
- [① 创建存储过程(查询用户信息)](#① 创建存储过程(查询用户信息))
- [② 调用存储过程](#② 调用存储过程)
- (2)触发器(自动触发执行)
-
- [① 创建触发器(用户删除时自动删除关联订单)](#① 创建触发器(用户删除时自动删除关联订单))
- [② 测试触发器](#② 测试触发器)
- [4. 主从复制(高可用+读写分离)](#4. 主从复制(高可用+读写分离))
-
- (1)主从复制核心原理
- [(2)主从复制配置步骤(MySQL 8.0)](#(2)主从复制配置步骤(MySQL 8.0))
-
- [① 主库配置(my.cnf 或 my.ini)](#① 主库配置(my.cnf 或 my.ini))
- [② 从库配置](#② 从库配置)
- [③ 主库创建复制用户并授权](#③ 主库创建复制用户并授权)
- [④ 从库配置主从关系](#④ 从库配置主从关系)
- (3)读写分离应用
- [四、MySQL 性能优化指南(生产环境核心)](#四、MySQL 性能优化指南(生产环境核心))
-
- [1. 索引优化(前文已讲,核心中的核心)](#1. 索引优化(前文已讲,核心中的核心))
- [2. SQL 语句优化](#2. SQL 语句优化)
- [3. 配置优化(my.cnf/my.ini)](#3. 配置优化(my.cnf/my.ini))
- [4. 慢查询分析](#4. 慢查询分析)
-
- (1)开启慢查询日志
- [(2)分析慢查询日志(使用 mysqldumpslow)](#(2)分析慢查询日志(使用 mysqldumpslow))
- [5. 分库分表(海量数据存储)](#5. 分库分表(海量数据存储))
- 五、常见问题排查与避坑指南
- 六、总结与进阶学习
-
- [1. 核心要点回顾](#1. 核心要点回顾)
- [2. 进阶学习方向](#2. 进阶学习方向)
- [3. 学习路径建议](#3. 学习路径建议)
前言
若对您有帮助的话,请点赞收藏加关注哦,您的关注是我持续创作的动力!有问题请私信或联系邮箱:funian.gm@gmail.com

MySQL 是全球最流行的开源关系型数据库(RDBMS),以其高性能、高可靠性、易用性和开源免费的特性,成为 Web 开发、大数据存储、企业级应用的首选数据库。本文从 MySQL 核心特性、安装部署、SQL 操作、高级功能到性能优化,覆盖从入门到生产环境的全场景需求,结合详细表格对比、可运行 SQL 示例和问题排查,帮助开发者快速掌握 MySQL 核心能力。
一、MySQL 核心特性与版本对比
1. 核心技术特性
| 特性 | 功能描述 | 应用场景 | 核心价值 |
|---|---|---|---|
| ACID 事务支持 | 原子性、一致性、隔离性、持久性,确保数据可靠性 | 金融交易、订单创建、支付转账等核心业务 | 避免数据丢失、不一致,保障业务正确性 |
| 多存储引擎 | 支持 InnoDB(默认)、MyISAM、Memory 等引擎 | 不同业务场景灵活选型(如 InnoDB 适合事务,Memory 适合缓存) | 按需优化性能、存储成本和功能支持 |
| 索引机制 | 支持 B+树索引、哈希索引、全文索引、空间索引 | 复杂查询提速、模糊搜索、地理位置查询 | 降低查询时间复杂度,从 O(n) 优化到 O(log n) |
| 分区表 | 将大表按规则拆分(范围、列表、哈希分区) | 海量数据存储(如千万级日志表、历史订单表) | 提升查询效率、简化数据归档和维护 |
| 主从复制 | 数据从主库同步到从库,支持读写分离 | 高并发场景(读多写少)、数据备份 | 分担主库压力,提高系统可用性和读写性能 |
| 存储过程/触发器 | 数据库端封装业务逻辑,自动触发执行 | 复杂数据校验、批量数据处理、日志自动记录 | 减少应用与数据库交互次数,提升执行效率 |
| 视图 | 虚拟表(基于 SQL 查询结果),隐藏数据结构 | 权限控制(隐藏敏感字段)、简化复杂查询 | 提高数据安全性,降低应用开发复杂度 |
| JSON 支持 | 原生支持 JSON 数据类型存储和查询 | 半结构化数据存储(如用户画像、配置信息) | 无需额外解析,直接操作 JSON 数据 |
2. 主流版本对比(选型指南)
| 版本系列 | 发布时间 | 支持周期 | 核心改进 | 适用场景 |
|---|---|---|---|---|
| MySQL 5.7 | 2015年 | 已停止支持(2023年10月) | 完善 InnoDB 性能、JSON 支持、多源复制 | legacy 系统、已有项目(不推荐新建) |
| MySQL 8.0 | 2018年 | 长期支持(至2030年) | 性能提升 2x+、窗口函数、CTE(公用表表达式)、角色管理 | 新建项目首选、企业级应用、高并发场景 |
| MariaDB 10.x | 基于 MySQL 分支 | 长期支持 | 兼容 MySQL 协议、新增 ColumnStore 引擎 | 追求开源自由、需要兼容 MySQL 的场景 |
选型建议:新建项目优先使用 MySQL 8.0,性能、安全性和功能均大幅优于 5.7,且长期支持有保障。
二、MySQL 基础入门(安装+连接+基础操作)
1. 安装与部署(3种方案)
(1)本地安装(Windows/macOS/Linux)
-
Windows:
- 下载安装包(https://dev.mysql.com/downloads/installer/);
- 双击安装,选择「Developer Default」,一路下一步(记得设置 root 密码);
- 验证:打开命令提示符,执行
mysql -u root -p,输入密码登录成功即完成。
-
macOS:
bash# brew 安装(推荐) brew install mysql@8.0 # 启动服务 brew services start mysql@8.0 # 初始化密码(首次启动) mysql_secure_installation -
Linux(Ubuntu):
bash# 安装 sudo apt update && sudo apt install -y mysql-server-8.0 # 启动服务 sudo systemctl start mysql # 设置开机自启 sudo systemctl enable mysql # 登录(默认无密码,直接回车) sudo mysql -u root
(2)Docker 部署(快速便捷,推荐)
bash
# 1. 拉取 MySQL 8.0 镜像
docker pull mysql:8.0
# 2. 启动容器(映射端口、设置密码、挂载数据卷)
docker run -d \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=test_db \
-v mysql-data:/var/lib/mysql \
--name mysql \
mysql:8.0
# 3. 进入容器终端
docker exec -it mysql bash
# 4. 登录 MySQL
mysql -u root -p123456
(3)云数据库(生产环境首选)
- 阿里云 RDS for MySQL:https://www.aliyun.com/product/rds/mysql
- 腾讯云 MySQL:https://cloud.tencent.com/product/cdb
- 优势:免运维、高可用、自动备份、弹性扩容,适合生产环境。
2. 连接 MySQL(4种方式)
| 连接方式 | 操作命令/步骤 | 适用场景 |
|---|---|---|
| 命令行(mysql-cli) | mysql -u 用户名 -p 密码 -h 主机IP -P 端口 -D 数据库名 |
快速测试、简单操作 |
| 图形化工具(Navicat) | 1. 新建连接;2. 填写主机、端口、用户名、密码;3. 连接 | 开发环境、复杂查询、可视化操作 |
| 编程语言(Java) | 使用 JDBC 驱动,通过 DriverManager 连接 |
项目开发、程序交互 |
| 编程语言(Python) | 使用 pymysql 库,创建连接对象 |
数据分析、脚本自动化 |
示例:
-
命令行连接本地 MySQL:
bashmysql -u root -p123456 -h localhost -P 3306 -D test_db -
Python 连接示例(
pymysql):pythonimport pymysql # 建立连接 conn = pymysql.connect( host='localhost', port=3306, user='root', password='123456', database='test_db', charset='utf8mb4' ) # 创建游标 cursor = conn.cursor() # 执行 SQL cursor.execute("SELECT VERSION()") # 获取结果 print("MySQL 版本:", cursor.fetchone()[0]) # 关闭连接 cursor.close() conn.close()
3. 数据库与表基础操作(SQL 命令)
(1)数据库操作
| 操作 | SQL 命令 | 实操示例 |
|---|---|---|
| 创建数据库 | CREATE DATABASE 数据库名 [CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci] |
CREATE DATABASE user_db CHARSET=utf8mb4;(支持 emoji) |
| 查看所有数据库 | SHOW DATABASES; |
SHOW DATABASES; |
| 切换数据库 | USE 数据库名; |
USE user_db; |
| 修改数据库字符集 | ALTER DATABASE 数据库名 CHARSET=utf8mb4; |
ALTER DATABASE user_db CHARSET=utf8mb4; |
| 删除数据库(谨慎!) | DROP DATABASE 数据库名; |
DROP DATABASE user_db; |
(2)表操作(DDL)
① 创建表(以用户表为例)
sql
USE user_db;
-- 创建用户表
CREATE TABLE `user` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '用户ID(主键)',
`username` VARCHAR(50) NOT NULL COMMENT '用户名(唯一)',
`password` VARCHAR(100) NOT NULL COMMENT '密码(加密存储)',
`phone` VARCHAR(20) DEFAULT NULL COMMENT '手机号',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`), -- 用户名唯一索引
KEY `idx_phone` (`phone`) -- 手机号普通索引
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
② 表结构操作
| 操作 | SQL 命令 | 实操示例 |
|---|---|---|
| 查看表结构 | DESC 表名; 或 SHOW COLUMNS FROM 表名; |
DESC user; |
| 查看表创建语句 | SHOW CREATE TABLE 表名; |
SHOW CREATE TABLE user; |
| 添加字段 | ALTER TABLE 表名 ADD COLUMN 字段名 类型 [约束] [COMMENT '描述']; |
ALTER TABLE user ADD COLUMN email VARCHAR(100) DEFAULT NULL COMMENT '邮箱'; |
| 修改字段类型 | ALTER TABLE 表名 MODIFY COLUMN 字段名 新类型; |
ALTER TABLE user MODIFY COLUMN phone VARCHAR(30); |
| 删除字段 | ALTER TABLE 表名 DROP COLUMN 字段名; |
ALTER TABLE user DROP COLUMN email; |
| 修改表名 | ALTER TABLE 旧表名 RENAME TO 新表名; |
ALTER TABLE user RENAME TO sys_user; |
| 删除表(谨慎!) | DROP TABLE 表名; |
DROP TABLE sys_user; |
(3)数据操作(DML)
| 操作 | SQL 命令 | 实操示例 |
|---|---|---|
| 插入数据 | INSERT INTO 表名(字段1,字段2) VALUES(值1,值2); |
INSERT INTO user(username, password, phone) VALUES('zhangsan', '123456', '13800138000'); |
| 批量插入 | INSERT INTO 表名(字段1,字段2) VALUES(值1,值2),(值3,值4); |
INSERT INTO user(username, password) VALUES('lisi', '654321'),('wangwu', 'abc123'); |
| 更新数据 | UPDATE 表名 SET 字段1=值1 WHERE 条件; |
UPDATE user SET phone='13900139000' WHERE username='zhangsan'; |
| 删除数据 | DELETE FROM 表名 WHERE 条件; |
DELETE FROM user WHERE username='wangwu'; |
| 清空表(保留结构) | TRUNCATE TABLE 表名; |
TRUNCATE TABLE user;(比 DELETE 快,无法回滚) |
(4)数据查询(DQL)
① 基础查询
sql
-- 查询所有字段(不推荐,性能差)
SELECT * FROM user;
-- 查询指定字段
SELECT id, username, phone FROM user;
-- 条件查询(WHERE)
SELECT * FROM user WHERE id > 1 AND phone IS NOT NULL;
-- 排序(ORDER BY):ASC 升序(默认),DESC 降序
SELECT * FROM user ORDER BY create_time DESC;
-- 分页查询(LIMIT):LIMIT 偏移量, 条数(偏移量从0开始)
SELECT * FROM user LIMIT 0, 10; -- 第1-10条
SELECT * FROM user LIMIT 10 OFFSET 10; -- 第11-20条(MySQL 8.0+支持)
-- 去重(DISTINCT)
SELECT DISTINCT phone FROM user;
② 聚合查询(GROUP BY + 聚合函数)
sql
-- 统计用户总数
SELECT COUNT(*) AS total FROM user;
-- 按手机号分组,统计每组用户数
SELECT phone, COUNT(*) AS count FROM user GROUP BY phone HAVING count > 1;
-- 求和、平均值、最大值、最小值
SELECT
SUM(id) AS sum_id,
AVG(id) AS avg_id,
MAX(create_time) AS latest_time,
MIN(create_time) AS earliest_time
FROM user;
③ 联表查询(多表关联)
假设有订单表 order:
sql
CREATE TABLE `order` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '订单ID',
`user_id` BIGINT NOT NULL COMMENT '关联用户ID',
`amount` DECIMAL(10,2) NOT NULL COMMENT '订单金额',
`status` TINYINT NOT NULL COMMENT '订单状态(0-待支付,1-已支付)',
PRIMARY KEY (`id`),
KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
联表查询示例:
sql
-- 内连接(INNER JOIN):只查询有订单的用户
SELECT u.username, o.id AS order_id, o.amount, o.status
FROM user u
INNER JOIN `order` o ON u.id = o.user_id;
-- 左连接(LEFT JOIN):查询所有用户,无订单则订单字段为 NULL
SELECT u.username, o.id AS order_id, o.amount
FROM user u
LEFT JOIN `order` o ON u.id = o.user_id;
-- 子查询(嵌套查询):查询订单金额大于 100 的用户
SELECT * FROM user
WHERE id IN (SELECT user_id FROM `order` WHERE amount > 100);
三、MySQL 核心高级功能(生产环境必备)
1. 索引优化(性能核心)
(1)索引类型与适用场景
| 索引类型 | 特点 | 适用场景 | 示例 |
|---|---|---|---|
| 主键索引(PRIMARY KEY) | 唯一且非空,加速主键查询 | 按主键查询(如 WHERE id=100) |
表创建时自动生成(id 字段) |
| 唯一索引(UNIQUE KEY) | 字段值唯一,加速查询+避免重复数据 | 用户名、手机号等唯一字段查询 | CREATE UNIQUE INDEX idx_username ON user(username); |
| 普通索引(KEY) | 无约束,单纯加速查询 | 频繁作为查询条件的字段(如 phone) |
CREATE INDEX idx_phone ON user(phone); |
| 联合索引(复合索引) | 多字段组合索引,遵循"最左前缀原则" | 多字段联合查询(如 WHERE username='a' AND phone='138') |
CREATE INDEX idx_uname_phone ON user(username, phone); |
| 全文索引(FULLTEXT) | 支持文本模糊搜索(如文章标题、内容) | 关键词搜索(如 WHERE MATCH(content) AGAINST('MySQL')) |
CREATE FULLTEXT INDEX idx_content ON article(content); |
(2)索引使用技巧与避坑
-
最左前缀原则 :联合索引
(a,b,c)仅支持a、a+b、a+b+c组合查询,不支持b、b+c单独查询; -
避免索引失效 :
失效场景 错误示例 优化方案 字段函数操作 WHERE DATE(create_time) = '2024-11-01'WHERE create_time BETWEEN '2024-11-01 00:00:00' AND '2024-11-01 23:59:59'模糊查询前缀通配符 WHERE username LIKE '%san'WHERE username LIKE 'zhang%'(后缀通配符不失效)隐式类型转换 WHERE phone = 13800138000(phone 是 VARCHAR)WHERE phone = '13800138000'(显式字符串匹配) -
索引设计原则 :
- 高频查询字段优先建索引;
- 避免过度索引(索引会降低插入/更新性能);
- 小字段优先建索引(如
INT比VARCHAR(255)更高效); - 联合索引将高频查询字段放在前面。
(3)索引查询与删除
sql
-- 查看表所有索引
SHOW INDEX FROM user;
-- 删除索引
DROP INDEX idx_phone ON user;
2. 事务管理(ACID 保障)
(1)事务控制命令
| 命令 | 功能描述 | 示例 |
|---|---|---|
START TRANSACTION |
开启事务 | START TRANSACTION; |
COMMIT |
提交事务(所有操作生效) | COMMIT; |
ROLLBACK |
回滚事务(撤销所有未提交操作) | ROLLBACK; |
SAVEPOINT 保存点 |
设置事务保存点(支持部分回滚) | SAVEPOINT sp1; |
ROLLBACK TO 保存点 |
回滚到指定保存点 | ROLLBACK TO sp1; |
SET AUTOCOMMIT |
设置自动提交(默认 ON,即每条 SQL 自动提交) | SET AUTOCOMMIT = OFF;(关闭自动提交) |
(2)事务隔离级别
MySQL 支持 4 种事务隔离级别(默认 REPEATABLE READ),解决脏读、不可重复读、幻读问题:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 适用场景 |
|---|---|---|---|---|
| READ UNCOMMITTED | 允许 | 允许 | 允许 | 无(性能差,无隔离) |
| READ COMMITTED | 禁止 | 允许 | 允许 | 大多数应用(如电商、社交) |
| REPEATABLE READ | 禁止 | 禁止 | 避免 | MySQL 默认级别,适合对一致性要求较高的场景 |
| SERIALIZABLE | 禁止 | 禁止 | 禁止 | 金融、支付等强一致性场景(性能最低) |
(3)事务实操示例(转账场景)
sql
SET AUTOCOMMIT = OFF;
START TRANSACTION;
-- 1. 扣减用户 A 余额
UPDATE user_account SET balance = balance - 100 WHERE user_id = 1;
-- 2. 增加用户 B 余额
UPDATE user_account SET balance = balance + 100 WHERE user_id = 2;
-- 检查操作是否正确(无异常则提交,有异常则回滚)
COMMIT;
-- ROLLBACK; -- 异常时执行回滚
3. 存储过程与触发器
(1)存储过程(数据库端业务逻辑封装)
① 创建存储过程(查询用户信息)
sql
DELIMITER // -- 临时修改语句结束符(默认 ; 会与存储过程内冲突)
CREATE PROCEDURE GetUserById(IN userId BIGINT, OUT userName VARCHAR(50))
BEGIN
-- 查询用户名赋值给输出参数
SELECT username INTO userName FROM user WHERE id = userId;
END //
DELIMITER ; -- 恢复默认结束符
② 调用存储过程
sql
-- 声明变量接收输出结果
SET @username = '';
-- 调用存储过程
CALL GetUserById(1, @username);
-- 查看结果
SELECT @username;
(2)触发器(自动触发执行)
① 创建触发器(用户删除时自动删除关联订单)
sql
DELIMITER //
CREATE TRIGGER DeleteUserOrderTrigger
AFTER DELETE ON user -- 删除用户后触发
FOR EACH ROW -- 每行数据触发一次
BEGIN
-- 删除关联的订单(OLD 表示删除前的用户记录)
DELETE FROM `order` WHERE user_id = OLD.id;
END //
DELIMITER ;
② 测试触发器
sql
-- 删除用户,触发器自动删除关联订单
DELETE FROM user WHERE id = 1;
4. 主从复制(高可用+读写分离)
(1)主从复制核心原理
- 主库(Master)将数据变更记录到二进制日志(binlog);
- 从库(Slave)开启 IO 线程,读取主库 binlog 并写入中继日志(relay log);
- 从库 SQL 线程解析中继日志,同步数据到从库。
(2)主从复制配置步骤(MySQL 8.0)
① 主库配置(my.cnf 或 my.ini)
ini
[mysqld]
server-id = 1 # 唯一标识(主从不能重复)
log-bin = mysql-bin # 开启二进制日志(主库必需)
binlog-format = ROW # 日志格式(推荐 ROW,基于行复制,数据一致性高)
② 从库配置
ini
[mysqld]
server-id = 2 # 唯一标识
relay-log = mysql-relay # 开启中继日志
③ 主库创建复制用户并授权
sql
-- 创建复制用户
CREATE USER 'repl'@'从库IP' IDENTIFIED BY '123456';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'从库IP';
-- 刷新权限
FLUSH PRIVILEGES;
-- 查看主库状态(记录 File 和 Position,从库配置用)
SHOW MASTER STATUS;
④ 从库配置主从关系
sql
-- 停止从库复制(首次配置前执行)
STOP SLAVE;
-- 配置主库信息
CHANGE MASTER TO
MASTER_HOST='主库IP',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_LOG_FILE='mysql-bin.000001', -- 主库 SHOW MASTER STATUS 输出的 File
MASTER_LOG_POS=156; -- 主库 SHOW MASTER STATUS 输出的 Position
-- 启动从库复制
START SLAVE;
-- 查看复制状态(Slave_IO_Running 和 Slave_SQL_Running 均为 Yes 则成功)
SHOW SLAVE STATUS\G;
(3)读写分离应用
- 主库:处理写操作(INSERT/UPDATE/DELETE);
- 从库:处理读操作(SELECT);
- 实现方式:应用层路由(如 MyBatis 读写分离插件)、中间件(如 Sharding-JDBC、ProxySQL)。
四、MySQL 性能优化指南(生产环境核心)
1. 索引优化(前文已讲,核心中的核心)
2. SQL 语句优化
| 优化方向 | 具体措施 | 错误示例 | 优化示例 |
|---|---|---|---|
| 避免 SELECT * | 只查询需要的字段 | SELECT * FROM user; |
SELECT id, username FROM user; |
| 优化 JOIN 语句 | 小表驱动大表,避免笛卡尔积 | 无索引 JOIN 大表 | 给 JOIN 字段建索引,小表作为驱动表 |
| 优化子查询 | 用 JOIN 替代子查询(子查询效率低) | SELECT * FROM user WHERE id IN (SELECT user_id FROM order); |
SELECT u.* FROM user u JOIN order o ON u.id = o.user_id; |
| 避免 LIMIT 偏移量过大 | 用主键分页(避免全表扫描) | SELECT * FROM user LIMIT 10000, 10; |
SELECT * FROM user WHERE id > 10000 LIMIT 10; |
| 优化聚合查询 | 给聚合字段建索引,避免临时表 | SELECT phone, COUNT(*) FROM user GROUP BY phone; |
给 phone 建索引,SELECT phone, COUNT(*) FROM user GROUP BY phone; |
3. 配置优化(my.cnf/my.ini)
| 配置项 | 功能描述 | 推荐值(4GB 内存服务器) |
|---|---|---|
innodb_buffer_pool_size |
InnoDB 缓存池大小(缓存数据和索引) | 2G(内存的 50%-70%) |
innodb_log_file_size |
InnoDB 日志文件大小 | 512M |
innodb_flush_log_at_trx_commit |
日志刷盘策略(1=同步刷盘,0=异步) | 1(核心业务,数据安全) |
max_connections |
最大连接数 | 1000(根据业务调整) |
query_cache_type |
查询缓存(MySQL 8.0 已移除) | 关闭(MySQL 5.7 设为 0) |
slow_query_log |
慢查询日志(记录执行时间>long_query_time 的 SQL) | ON |
long_query_time |
慢查询阈值(秒) | 1(记录执行时间>1 秒的 SQL) |
4. 慢查询分析
(1)开启慢查询日志
sql
-- 临时开启(重启失效)
SET GLOBAL slow_query_log = ON;
SET GLOBAL long_query_time = 1;
-- 永久开启(修改 my.cnf)
[mysqld]
slow_query_log = ON
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1
(2)分析慢查询日志(使用 mysqldumpslow)
bash
# 查看慢查询 TOP 10
mysqldumpslow -s r -t 10 /var/log/mysql/slow.log
# -s r:按查询时间排序;-t 10:显示前 10 条
5. 分库分表(海量数据存储)
当单表数据量超过 1000 万条时,需进行分库分表:
(1)分表方式
| 分表方式 | 特点 | 适用场景 | 实现工具 |
|---|---|---|---|
| 水平分表(按行拆分) | 同一表拆分为多个表(如 order_202401、order_202402) | 时间范围数据(如订单、日志) | Sharding-JDBC、MyCat |
| 垂直分表(按列拆分) | 大表拆分为小表(如 user 拆分为 user_basic、user_detail) | 表字段过多,部分字段不常用 | 应用层手动拆分 |
| 分库分表(水平+垂直) | 多库多表拆分(如 db1.user_1、db2.user_2) | 超大规模数据(亿级) | Sharding-JDBC、MyCat |
(2)水平分表示例(按订单时间分表)
- 订单表拆分为
order_202401、order_202402、order_202403等; - 应用层根据订单时间路由到对应的分表(如 2024 年 1 月的订单写入
order_202401)。
五、常见问题排查与避坑指南
| 问题现象 | 可能原因 | 排查步骤 | 解决方案 |
|---|---|---|---|
连接失败(Access denied for user) |
1. 用户名/密码错误;2. 主机IP未授权;3. 数据库不存在 | 1. 验证用户名密码;2. 查看用户授权(SELECT user,host FROM mysql.user;);3. 确认数据库存在 |
1. 重置密码(ALTER USER 'root'@'localhost' IDENTIFIED BY 'newpwd';);2. 授权(GRANT ALL ON *.* TO 'root'@'%' WITH GRANT OPTION;);3. 创建数据库 |
| 索引失效(查询缓慢) | 1. 违反最左前缀原则;2. 字段函数操作;3. 模糊查询前缀通配符 | 1. 查看 SQL 执行计划(EXPLAIN SELECT * FROM user WHERE phone='138';);2. 检查索引是否存在;3. 分析 SQL 语法 |
1. 调整查询条件符合索引规则;2. 避免字段函数操作;3. 给查询字段建索引 |
| 事务回滚失败 | 1. 表引擎不是 InnoDB(MyISAM 不支持事务);2. 自动提交未关闭;3. 异常未抛出 | 1. 查看表引擎(SHOW TABLE STATUS LIKE 'user';);2. 检查 AUTOCOMMIT 状态;3. 查看事务执行日志 |
1. 转换表引擎(ALTER TABLE user ENGINE=InnoDB;);2. 关闭自动提交(SET AUTOCOMMIT=OFF;);3. 手动抛出异常并执行 ROLLBACK |
| 主从复制失败(Slave_IO_Running=No) | 1. 主从 server-id 重复;2. 复制用户权限不足;3. 主库 binlog 文件不存在 | 1. 检查主从 server-id 配置;2. 验证复制用户权限;3. 查看主库 binlog 状态(SHOW MASTER LOGS;) |
1. 修改 server-id 为唯一值;2. 重新授权复制用户;3. 重新配置主从关系(CHANGE MASTER TO) |
| 慢查询(执行时间>1秒) | 1. 未建索引;2. SQL 语法优化;3. 数据量过大 | 1. 开启慢查询日志;2. 用 EXPLAIN 分析执行计划;3. 查看表数据量 |
1. 给查询字段建索引;2. 优化 SQL 语句;3. 分库分表 |
六、总结与进阶学习
1. 核心要点回顾
- MySQL 核心优势:ACID 事务、高性能索引、多存储引擎、开源免费,适合从单体到分布式的全场景;
- 基础操作:掌握数据库/表 CRUD、SQL 查询(联表、聚合、分页);
- 高级功能:索引优化(性能核心)、事务管理(数据可靠)、主从复制(高可用)、存储过程(逻辑封装);
- 生产环境必备:性能优化(索引+SQL+配置)、慢查询分析、分库分表、主从复制。
2. 进阶学习方向
| 学习方向 | 核心内容 | 推荐资源 |
|---|---|---|
| 源码解析 | InnoDB 存储引擎原理、事务隔离实现、索引结构 | 《MySQL 技术内幕:InnoDB 存储引擎》 |
| 高可用架构 | 主从复制、MGR(MySQL Group Replication)、集群部署 | MySQL 官方文档、《高性能 MySQL》 |
| 云原生部署 | Docker+K8s 部署 MySQL、云数据库(RDS)最佳实践 | 阿里云 RDS 文档、K8s 官方文档 |
| 数据治理 | 数据备份与恢复、数据迁移、数据安全 | 《MySQL 备份与恢复实战》 |
3. 学习路径建议
- 基础阶段:安装部署 → 基础 SQL → 表操作 → 简单查询;
- 进阶阶段:索引优化 → 事务管理 → 存储过程/触发器 → 主从复制;
- 实战阶段:性能优化 → 慢查询分析 → 分库分表 → 高可用集群;
- 高级阶段:源码解析 → 云原生部署 → 大规模集群运维。
MySQL 学习的关键是"理论+实操+优化",从简单的 SQL 编写入手,逐步过渡到复杂查询和性能优化,结合实际项目场景积累经验。如果遇到具体技术问题,可参考官方文档或社区(Stack Overflow、MySQL 中文网),也欢迎在评论区留言讨论~