markdown复制## 1. MySQL表操作基础与核心概念
作为关系型数据库的典型代表,MySQL的表操作构成了数据管理的基石。在实际项目中,合理的表结构设计和高效的数据查询往往直接影响着系统性能。我们先从最基础的建表操作说起:
创建表时除了字段定义,还需要特别注意引擎选择。以常用的InnoDB引擎为例,它支持事务和行级锁,适合大多数OLTP场景。建表语句中的关键参数包括:
```sql
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
注意:字符集推荐使用utf8mb4而非utf8,前者完整支持emoji等4字节字符,避免出现存储异常
字段类型选择直接影响存储效率和查询性能:
- 整型:根据数据范围选择TINYINT/SMALLINT/INT/BIGINT
- 字符串:定长用CHAR,变长用VARCHAR(超过255字符考虑TEXT)
- 时间:TIMESTAMP占用4字节,DATETIME占用8字节
2. 表结构优化实战技巧
2.1 索引设计黄金法则
索引是把双刃剑,合理使用能提升查询效率,滥用则会导致写入性能下降。复合索引的字段顺序遵循"最左前缀原则":
sql复制-- 有效使用索引的情况
SELECT * FROM orders WHERE user_id=100 AND status='paid'
-- 索引定义
ALTER TABLE orders ADD INDEX idx_user_status (user_id, status);
常见索引失效场景:
- 对索引列使用函数:
WHERE DATE(create_time)='2023-01-01' - 隐式类型转换:
WHERE user_id='100'(user_id是整型) - 前导模糊查询:
WHERE name LIKE '%张'
2.2 分区表实战应用
当单表数据量超过千万级时,可以考虑分区策略。按时间范围分区是常见做法:
sql复制CREATE TABLE logs (
id INT AUTO_INCREMENT,
log_time DATETIME,
content TEXT,
PRIMARY KEY (id, log_time)
) PARTITION BY RANGE (TO_DAYS(log_time)) (
PARTITION p202301 VALUES LESS THAN (TO_DAYS('2023-02-01')),
PARTITION p202302 VALUES LESS THAN (TO_DAYS('2023-03-01'))
);
分区表使用注意事项:
- 查询条件必须包含分区键,否则会扫描所有分区
- 唯一索引必须包含分区字段
- 分区数量不宜过多(通常不超过1024个)
3. 高效查询编写指南
3.1 EXPLAIN执行计划深度解析
理解EXPLAIN输出是优化查询的基础,关键指标解读:
| 列名 | 关键值 | 含义 |
|---|---|---|
| type | const/ref/range/index | 访问类型,性能从优到劣 |
| rows | 估算行数 | 需要检查的行数预估 |
| Extra | Using filesort | 需要额外排序,可能性能瓶颈 |
典型优化案例:
sql复制-- 优化前(全表扫描)
EXPLAIN SELECT * FROM products WHERE price > 100 ORDER BY create_time DESC;
-- 优化后(使用索引覆盖)
ALTER TABLE products ADD INDEX idx_price_time (price, create_time);
EXPLAIN SELECT id, price FROM products WHERE price > 100 ORDER BY create_time DESC;
3.2 联表查询性能陷阱
多表JOIN时容易出现性能问题,需要特别注意:
- 小表驱动原则:将数据量小的表作为驱动表
sql复制-- 推荐:user表数据量远小于orders
SELECT * FROM user u JOIN orders o ON u.id=o.user_id
- 避免笛卡尔积:确保ON条件有效
sql复制-- 错误示例:漏写关联条件导致全量组合
SELECT * FROM A, B WHERE A.status=1
- 子查询优化:能用JOIN尽量不用子查询
sql复制-- 不推荐
SELECT * FROM products WHERE category_id IN
(SELECT id FROM categories WHERE type='electronics')
-- 推荐
SELECT p.* FROM products p JOIN categories c
ON p.category_id=c.id WHERE c.type='electronics'
4. 高级查询技术与实战案例
4.1 窗口函数应用场景
MySQL 8.0+支持的窗口函数能简化复杂分析查询:
sql复制-- 计算每个部门的薪资排名
SELECT
name, department, salary,
RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rank
FROM employees;
常用窗口函数:
- ROW_NUMBER(): 无重复序号
- RANK(): 并列排名会跳过序号
- DENSE_RANK(): 并列排名不跳过序号
- LAG/LEAD(): 访问前后行数据
4.2 公用表表达式(CTE)优化复杂查询
CTE能提升复杂查询的可读性和性能:
sql复制-- 找出销售额前10%的商品
WITH product_sales AS (
SELECT
product_id,
SUM(amount) AS total_sales,
PERCENT_RANK() OVER (ORDER BY SUM(amount) DESC) AS pct_rank
FROM order_items
GROUP BY product_id
)
SELECT * FROM product_sales WHERE pct_rank <= 0.1;
CTE的典型优势:
- 替代嵌套子查询,提升可读性
- 支持递归查询(处理树形数据)
- 可被多次引用,避免重复计算
5. 生产环境避坑指南
5.1 大表ALTER操作方案
线上修改大表结构是高风险操作,推荐使用pt-online-schema-change工具。其原理是:
- 创建影子表(新结构)
- 建立触发器同步数据变更
- 分批拷贝原表数据
- 原子性切换表名
手动实现的基本流程:
sql复制-- 1. 创建新表
CREATE TABLE new_users LIKE users;
ALTER TABLE new_users ADD COLUMN age TINYINT;
-- 2. 分批拷贝数据
INSERT INTO new_users SELECT * FROM users WHERE id BETWEEN 1 AND 10000;
-- ...多次分批执行...
-- 3. 原子切换
RENAME TABLE users TO old_users, new_users TO users;
5.2 慢查询日志分析技巧
开启慢查询日志并配置阈值(单位秒):
ini复制# my.cnf配置
slow_query_log = 1
slow_query_log_file = /var/log/mysql/mysql-slow.log
long_query_time = 1
log_queries_not_using_indexes = 1
使用mysqldumpslow工具分析:
bash复制# 统计最耗时的10个查询
mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log
# 解析特定查询模式
mysqldumpslow -g "SELECT FROM products" mysql-slow.log
对于复杂分析,推荐使用Percona的pt-query-digest工具:
bash复制pt-query-digest /var/log/mysql/mysql-slow.log > slow_report.txt
6. 性能优化进阶策略
6.1 查询重写黄金法则
- 只返回必要字段:避免SELECT *
sql复制-- 优化前
SELECT * FROM users WHERE status=1;
-- 优化后
SELECT id, name FROM users WHERE status=1;
- 利用覆盖索引:索引包含所有查询字段
sql复制-- 添加覆盖索引
ALTER TABLE orders ADD INDEX idx_user_date (user_id, create_date);
-- 查询使用覆盖索引
EXPLAIN SELECT user_id, create_date FROM orders
WHERE user_id=100 AND create_date>'2023-01-01';
- 分批处理大数据量:避免单次操作过多数据
sql复制-- 批量删除优化
DELETE FROM logs WHERE created_at < '2022-01-01' LIMIT 1000;
-- 循环执行直到影响行数为0
6.2 连接池与预处理语句
正确配置连接池参数(以HikariCP为例):
java复制HikariConfig config = new HikariConfig();
config.setMaximumPoolSize(20); // 建议值:(核心数*2)+有效磁盘数
config.setConnectionTimeout(30000);
config.setIdleTimeout(600000);
预处理语句能提升性能并防止SQL注入:
java复制// Java示例
String sql = "SELECT * FROM users WHERE username = ?";
PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setString(1, inputUsername);
ResultSet rs = stmt.executeQuery();
MySQL服务端预处理协议有两种模式:
- 文本协议(默认):SQL和参数分开发送
- 二进制协议(推荐):更高效的数据传输
7. 数据安全与备份策略
7.1 敏感数据加密方案
字段级加密推荐使用AES算法:
sql复制-- 加密存储
INSERT INTO users (username, password) VALUES (
'admin',
AES_ENCRYPT('mypassword', 'encryption_key')
);
-- 解密查询
SELECT username, AES_DECRYPT(password, 'encryption_key')
FROM users WHERE username='admin';
重要提示:加密密钥必须安全存储,建议使用专业密钥管理系统(如Vault),避免硬编码在应用中
7.2 可靠备份方案设计
生产环境备份策略组合:
- 全量备份:每周一次,使用mysqldump或xtrabackup
bash复制# mysqldump示例
mysqldump --single-transaction --master-data=2 \
-u root -p mydatabase > backup_$(date +%F).sql
- 增量备份:每日binlog备份
bash复制# 定时刷新binlog并备份
mysqladmin flush-logs
cp /var/lib/mysql/mysql-bin.00000* /backup/
- 备份验证:定期进行恢复测试
bash复制# 创建测试实例
mysql -e "CREATE DATABASE backup_test"
mysql backup_test < backup_2023-08-01.sql
备份文件存储建议遵循3-2-1原则:
- 至少3份副本
- 存储在2种不同介质
- 1份异地备份
8. 查询模式与反模式
8.1 高效分页方案对比
常见分页方案性能比较:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| LIMIT offset, size | 实现简单 | 偏移量大时性能差 | 小数据量/前端分页 |
| 游标分页 | 性能稳定 | 需要连续有序字段 | 无限滚动/大数据量 |
| 覆盖索引+JOIN | 避免回表 | 实现复杂 | 固定排序的大表查询 |
游标分页实现示例:
sql复制-- 第一页
SELECT * FROM items WHERE id > 0 ORDER BY id LIMIT 10;
-- 后续页(last_id为上页最后记录的ID)
SELECT * FROM items WHERE id > last_id ORDER BY id LIMIT 10;
8.2 事务使用最佳实践
合理控制事务范围和隔离级别:
sql复制-- 明确设置隔离级别
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
-- 业务操作
UPDATE accounts SET balance=balance-100 WHERE user_id=1;
UPDATE orders SET status='paid' WHERE id=1001;
COMMIT;
事务设计原则:
- 尽量短小:不在事务中包含网络请求等耗时操作
- 合理设置隔离级别:默认REPEATABLE READ可能造成锁等待
- 避免死锁:多表操作保持一致的访问顺序
9. 监控与性能调优
9.1 关键性能指标监控
必备监控项及其阈值建议:
| 指标 | 预警阈值 | 采集方式 |
|---|---|---|
| QPS | > 5000 | SHOW GLOBAL STATUS |
| 连接数利用率 | > 80% | SHOW PROCESSLIST |
| 缓存命中率 | < 95% | SHOW ENGINE INNODB STATUS |
| 复制延迟 | > 60秒 | SHOW SLAVE STATUS |
性能视图查询技巧:
sql复制-- 查看当前锁等待
SELECT * FROM performance_schema.events_waits_current
WHERE EVENT_NAME LIKE '%lock%';
-- 统计表访问热度
SELECT OBJECT_SCHEMA, OBJECT_NAME, COUNT_READ
FROM performance_schema.table_io_waits_summary_by_table
ORDER BY COUNT_READ DESC LIMIT 10;
9.2 配置参数调优指南
关键参数调整建议(基于8核32GB内存的专用数据库服务器):
ini复制[mysqld]
# 缓冲池大小(总内存的50-70%)
innodb_buffer_pool_size = 16G
# 日志文件大小(缓冲池的25%)
innodb_log_file_size = 4G
# 连接数配置
max_connections = 200
thread_cache_size = 50
# 其他优化
innodb_flush_neighbors = 0 # SSD建议关闭
innodb_io_capacity = 2000 # SSD可提高
参数调整后必须监控以下指标:
- 缓冲池命中率(应>95%)
- 脏页比例(应<10%)
- 线程缓存命中率(应>90%)
10. 实战:电商系统查询优化
10.1 商品搜索场景优化
典型商品搜索SQL及优化路径:
sql复制-- 原始查询
SELECT * FROM products
WHERE name LIKE '%手机%'
AND price BETWEEN 1000 AND 5000
ORDER BY sales DESC
LIMIT 0, 20;
-- 优化方案
ALTER TABLE products ADD FULLTEXT INDEX idx_name (name);
ALTER TABLE products ADD INDEX idx_price_sales (price, sales);
-- 优化后查询
SELECT * FROM products
WHERE MATCH(name) AGAINST('手机' IN BOOLEAN MODE)
AND price BETWEEN 1000 AND 5000
ORDER BY price, sales DESC
LIMIT 0, 20;
搜索优化策略组合:
- 全文索引替代LIKE模糊查询
- 使用固定排序条件利用索引
- 结果集限制合理分页大小
10.2 订单统计报表优化
月销售统计查询优化对比:
sql复制-- 优化前(全表扫描)
SELECT
DATE_FORMAT(create_time,'%Y-%m') AS month,
COUNT(*) AS order_count,
SUM(amount) AS total_amount
FROM orders
WHERE create_time BETWEEN '2022-01-01' AND '2022-12-31'
GROUP BY month;
-- 优化方案:预聚合+定期刷新
CREATE TABLE order_monthly_stats (
month VARCHAR(7) PRIMARY KEY,
order_count INT,
total_amount DECIMAL(12,2)
);
-- 使用事件定期更新
CREATE EVENT update_order_stats
ON SCHEDULE EVERY 1 DAY
DO
INSERT INTO order_monthly_stats
SELECT
DATE_FORMAT(create_time,'%Y-%m'),
COUNT(*),
SUM(amount)
FROM orders
WHERE create_time >= DATE_FORMAT(NOW(),'%Y-%m-01')
ON DUPLICATE KEY UPDATE
order_count=VALUES(order_count),
total_amount=VALUES(total_amount);
报表优化通用策略:
- 预聚合高频查询指标
- 使用物化视图或汇总表
- 错峰计算(夜间批量作业)
11. 分布式方案演进
11.1 读写分离实现模式
典型读写分离架构实现方式:
-
中间件代理(如MyCat、ProxySQL)
- 优点:对应用透明
- 缺点:增加网络跳数
-
客户端分片(如ShardingSphere-JDBC)
- 优点:性能更好
- 缺点:需修改应用代码
配置示例(Spring Boot):
properties复制# 主库
spring.datasource.master.url=jdbc:mysql://master:3306/db
spring.datasource.master.username=root
spring.datasource.master.password=123456
# 从库
spring.datasource.slave.url=jdbc:mysql://slave:3306/db
spring.datasource.slave.username=readonly
spring.datasource.slave.password=123456
11.2 分库分表实战策略
水平分片常见路由策略:
-
范围分片:按ID范围或时间范围
- 优点:易于扩容
- 缺点:可能数据分布不均
-
哈希分片:按分片键哈希值
- 优点:数据分布均匀
- 缺点:扩容复杂
-
目录分片:维护路由表
- 优点:灵活度高
- 缺点:维护成本高
分片键选择原则:
- 避免热点(如不要用性别作为分片键)
- 常用查询条件应包含分片键
- 尽量选择值不重复的字段
12. 新版本特性应用
12.1 MySQL 8.0窗口函数实战
典型业务场景:计算移动平均
sql复制SELECT
date,
sales,
AVG(sales) OVER (ORDER BY date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS moving_avg
FROM daily_sales;
高级分析函数应用:
sql复制-- 计算同比环比
SELECT
month,
revenue,
LAG(revenue, 1) OVER (ORDER BY month) AS prev_month,
revenue - LAG(revenue, 1) OVER (ORDER BY month) AS mom_growth,
LAG(revenue, 12) OVER (ORDER BY month) AS prev_year,
revenue - LAG(revenue, 12) OVER (ORDER BY month) AS yoy_growth
FROM monthly_revenue;
12.2 JSON类型高效使用
JSON字段操作示例:
sql复制-- 创建包含JSON列的表
CREATE TABLE products (
id INT PRIMARY KEY,
details JSON,
price DECIMAL(10,2)
);
-- 插入JSON数据
INSERT INTO products VALUES (1,
'{"name":"手机","specs":{"ram":"8GB","storage":"128GB"}}',
2999.00
);
-- 查询JSON属性
SELECT
id,
details->"$.name" AS product_name,
details->"$.specs.ram" AS memory
FROM products
WHERE details->"$.specs.storage" = '128GB';
JSON索引优化:
sql复制-- 为JSON字段创建虚拟列并加索引
ALTER TABLE products ADD COLUMN ram_size VARCHAR(10)
GENERATED ALWAYS AS (details->"$.specs.ram") VIRTUAL;
ALTER TABLE products ADD INDEX idx_ram (ram_size);
13. 运维监控体系搭建
13.1 监控指标采集方案
推荐监控指标体系:
-
基础资源层:
- CPU使用率(user% < 70%)
- 内存使用(used < 80%)
- 磁盘IOPS(< 80%容量)
-
MySQL服务层:
- 活跃线程数(Threads_running < 50)
- 查询缓存命中率(> 95%)
- 临时表创建数(Created_tmp_tables < 100/s)
-
业务指标层:
- 慢查询率(< 1%)
- 主从延迟(Seconds_Behind_Master < 30)
Prometheus采集配置示例:
yaml复制scrape_configs:
- job_name: 'mysql'
static_configs:
- targets: ['mysql-exporter:9104']
params:
collect[]:
- global_status
- innodb_metrics
- performance_schema.events_statements_summary_by_digest
13.2 自动化运维实践
常用自动化场景实现:
- 慢查询自动报警
bash复制# 每日分析慢查询日志
pt-query-digest /var/log/mysql/mysql-slow.log | \
grep -A 3 'Profile' | \
mail -s "MySQL Slow Query Report" dba@example.com
- 空间不足自动扩容
python复制# 监控表空间脚本
import MySQLdb
db = MySQLdb.connect(host="localhost", user="monitor")
cursor = db.cursor()
cursor.execute("SELECT table_schema, sum(data_length)/1024/1024 \
FROM information_schema.tables GROUP BY table_schema")
for row in cursor.fetchall():
if row[1] > 10240: # 超过10GB
send_alert(f"Database {row[0]} exceeds 10GB")
- 连接数异常自动重启
bash复制# 监控连接数脚本
connections=$(mysql -e "SHOW STATUS LIKE 'Threads_connected'" | awk 'NR==2{print $2}')
if [ $connections -gt 200 ]; then
systemctl restart mysql
echo "$(date) MySQL restarted due to high connections" >> /var/log/mysql-monitor.log
fi
14. 故障排查手册
14.1 常见问题速查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 查询突然变慢 | 索引失效/统计信息过期 | ANALYZE TABLE更新统计信息 |
| 连接数暴涨 | 连接泄漏/慢查询堆积 | 杀掉异常连接并优化查询 |
| 主从复制中断 | 数据冲突/网络问题 | 跳过错误或重建复制 |
| 磁盘空间不足 | 大事务/binlog堆积 | 清理旧数据/扩容磁盘 |
14.2 死锁分析与解决
死锁日志分析步骤:
- 开启死锁日志记录
ini复制# my.cnf
innodb_print_all_deadlocks = 1
- 分析死锁日志(SHOW ENGINE INNODB STATUS)
code复制LATEST DETECTED DEADLOCK
------------------------
2023-08-01 10:00:00
*** (1) TRANSACTION:
TRANSACTION 12345, ACTIVE 2 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 100, OS thread handle 123, query id 1000 updating
UPDATE accounts SET balance=balance-100 WHERE user_id=1
*** (2) TRANSACTION:
TRANSACTION 12346, ACTIVE 1 sec starting index read
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1136, 2 row lock(s)
MySQL thread id 101, OS thread handle 124, query id 1001 updating
UPDATE accounts SET balance=balance+100 WHERE user_id=2
- 解决方案:
- 调整事务顺序(按固定顺序访问表)
- 减小事务范围
- 添加合适的索引减少锁定范围
15. 最佳实践总结
15.1 设计规范精华
表设计黄金法则:
- 每个表必须有主键(推荐自增INT/BIGINT)
- 字段选择最小满足原则(能用TINYINT不用INT)
- 避免NULL字段(用默认值替代)
- 大字段(如TEXT/BLOB)分离到单独表
索引设计原则:
- 单表索引不超过5个
- 复合索引字段数不超过3个
- 区分度高的字段在前(如性别不适合建索引)
- 频繁更新的字段谨慎建索引
15.2 性能优化检查清单
上线前必查项:
- 所有查询是否都有EXPLAIN分析?
- 大表是否添加了合适的分区策略?
- 事务隔离级别是否明确设置?
- 连接池配置是否经过压力测试?
- 监控告警是否覆盖关键指标?
日常维护重点:
- 每周检查慢查询日志
- 每月更新统计信息(ANALYZE TABLE)
- 每季度review索引使用情况
- 定期验证备份有效性
16. 工具链推荐
16.1 开发辅助工具
-
可视化工具:
- MySQL Workbench(官方工具)
- DBeaver(开源跨平台)
- Navicat(商业版功能强大)
-
SQL审核:
- Yearning(开源SQL审核平台)
- Archery(数据库管理平台)
-
测试数据生成:
- SysBench(压力测试)
- Mockaroo(模拟数据生成)
16.2 运维监控工具
-
性能分析:
- pt-query-digest(慢查询分析)
- mysqlsla(日志分析)
-
监控平台:
- Prometheus + Grafana(指标可视化)
- Zabbix(企业级监控)
-
备份恢复:
- XtraBackup(物理备份)
- mydumper(逻辑备份)
17. 学习路径建议
17.1 知识体系构建
MySQL技能进阶路线:
-
基础阶段:
- 安装配置
- 基本CRUD操作
- 简单索引使用
-
中级阶段:
- 执行计划分析
- 事务隔离级别
- 主从复制配置
-
高级阶段:
- 性能调优
- 高可用架构
- 分布式方案
17.2 推荐学习资源
经典书籍:
- 《高性能MySQL》(必读)
- 《MySQL技术内幕:InnoDB存储引擎》
- 《数据库索引设计与优化》
在线资源:
- MySQL官方文档(8.0版本)
- Percona博客(实战案例丰富)
- 阿里云数据库技术专栏
实践建议:
- 本地搭建测试环境故意制造性能问题
- 参与开源数据库项目贡献
- 定期复盘线上事故案例
18. 未来趋势展望
18.1 新硬件适配优化
-
SSD优化方向:
- 调整innodb_io_capacity参数
- 关闭innodb_flush_neighbors
- 使用O_DIRECT方式避免双缓冲
-
持久内存(PMEM)应用:
- 将redo log放在PMEM设备
- 使用内存池快速恢复
-
GPU加速:
- 复杂分析查询卸载到GPU
- 机器学习推理加速
18.2 云原生演进趋势
-
Serverless数据库:
- 自动弹性伸缩
- 按实际使用量计费
-
智能优化器:
- 基于机器学习的查询优化
- 自动索引推荐
-
多模数据库:
- 原生JSON支持增强
- 图查询能力集成
- 时序数据处理优化
19. 个人经验分享
在多年的MySQL优化实践中,有几个深刻体会:
-
预防优于治疗:良好的设计比后期优化更重要。曾经遇到一个没有主键的表,数据量到百万级后各种诡异问题频出,最终不得不停机改造。
-
工具善其事:pt工具链几乎成了DBA的瑞士军刀。特别是pt-query-digest分析慢查询日志,能快速定位核心问题。
-
监控即生命线:没有完善的监控就像闭眼开车。建议至少监控:QPS、连接数、缓冲池命中率、复制延迟这四个黄金指标。
-
简单即美:过度设计往往带来更多问题。见过有人为每个字段都建索引,结果写入性能下降80%。记住索引不是越多越好。
一个实用小技巧:在开发环境设置long_query_time=0记录所有查询,可以全面了解应用SQL模式,这个在初期设计阶段特别有用。
20. 互动答疑
最后整理几个常见问题解答:
Q:为什么COUNT(*)这么慢?
A:MyISAM引擎的COUNT(*)很快是因为维护了计数器,而InnoDB需要实际扫描。优化方案:
- 使用估算值:
SHOW TABLE STATUS的Rows字段 - 维护计数表
- 对大数据量使用EXPLAIN估算
Q:如何选择存储引擎?
A:常规选择:
- 需要事务:InnoDB
- 只读日志表:MyISAM(MySQL 8.0+推荐改用InnoDB)
- 临时处理:Memory引擎
注意:MySQL 8.0+已经将InnoDB作为默认且唯一支持事务的引擎
Q:大字段存储优化方案?
A:处理TEXT/BLOB字段的建议:
- 分离到单独表
- 考虑使用文件存储,数据库中只保存路径
- 启用innodb_large_prefix(MySQL 5.7+默认开启)
- 避免在大字段上建索引
Q:如何安全地进行表结构变更?
A:线上DDL操作建议流程:
- 先在从库执行,观察影响
- 使用pt-online-schema-change工具
- 低峰期操作
- 确保有回滚方案(如备份原表)
Q:连接数暴增如何应急?
A:紧急处理步骤:
- 快速重启MySQL服务(极端情况)
- 使用
SHOW PROCESSLIST找出异常连接 KILL掉非关键连接- 临时调整max_connections参数
事后必须分析原因,可能是连接泄漏或突发流量导致
code复制