在 1 核 1G 的服务器上优化数据库性能,核心思路是减少资源争用、降低内存/磁盘压力、避免无效查询。以下是针对常见场景(以 MySQL/MariaDB 为主)的实用优化策略:
🔧 一、数据库配置调优(关键!)
1. 限制内存占用
innodb_buffer_pool_size:设为总内存的 30%~40%(即 256MB~400MB),避免 OOM。[mysqld] innodb_buffer_pool_size = 384M innodb_log_file_size = 64M # 减小日志文件,加快刷新 innodb_flush_method = O_DIRECT # 绕过系统缓存,减少双重缓冲 max_connections = 20 # 限制并发连接数(默认可能过高) thread_cache_size = 10 query_cache_type = 0 # MySQL 8.0+ 已移除;旧版建议关闭(高并发下反成瓶颈)- 禁用不必要功能:如
slow_query_log可临时关闭(生产需保留但限时长)。
2. 调整 InnoDB 参数
innodb_flush_log_at_trx_commit = 2 # 牺牲少量持久性换速度(非强事务要求时)
innodb_io_capacity = 200 # SSD 可设 1000+;机械盘保持 200
innodb_read_io_threads = 1 # 单核环境不宜多
innodb_write_io_threads = 1
✅ 验证:
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
⚠️ 重启生效:sudo systemctl restart mysql
📉 二、查询与索引优化
- 避免全表扫描:用
EXPLAIN分析慢查询,确保 WHERE/JOIN 字段有索引。EXPLAIN SELECT * FROM users WHERE email = 'test@example.com'; - 只查必要字段:禁止
SELECT *,明确指定列。 - 分页优化:大 offset 改用游标或延迟关联:
-- 推荐方式(假设 id 连续) SELECT * FROM orders WHERE id > 10000 LIMIT 20; - 定期清理无用索引:监控未命中索引:
SELECT table_name, index_name, seq_in_index FROM information_schema.statistics WHERE table_schema = 'your_db' ORDER BY table_name, seq_in_index;
💾 三、存储与文件系统层优化
- 使用 tmpfs 做临时目录(提升临时表/排序速度):
mkdir -p /tmp/mysql-tmp mount -t tmpfs -o size=256M tmpfs /tmp/mysql-tmp # 修改 my.cnf: tmpdir = /tmp/mysql-tmp - 启用压缩表(适合读多写少):
ALTER TABLE large_table ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; - 文件系统选择:优先 ext4/xfs +
noatime挂载选项:/dev/sda1 /var/lib/mysql ext4 defaults,noatime,nodiratime 0 2
🛡️ 四、应用层协同优化
- 连接池复用:避免频繁新建连接(如 PHP 用 PDO 连接池,Java 用 HikariCP)。
- 批量操作替代循环:将多条 INSERT/UPDATE 合并为一条。
- 读写分离(若架构允许):主库写,从库读(即使单机也可模拟分库逻辑)。
📊 五、监控与诊断工具
| 工具 | 用途 |
|---|---|
mysqladmin processlist |
实时查看活跃连接 |
pt-query-digest |
分析慢查询日志(Percona Toolkit) |
vmstat 1 / iostat -x 1 |
检查 CPU/IO 瓶颈 |
htop |
观察进程内存/CPU 占用 |
💡 提示:开启慢查询日志仅用于诊断,阈值设为 1~2 秒即可:
slow_query_log = 1 long_query_time = 2 log_queries_not_using_indexes = 1
❌ 避免的误区
- 盲目增大 buffer_pool → 导致 swap 交换,性能暴跌。
- 过度使用触发器/存储过程 → 增加解析开销。
- 忽略字符集影响 →
utf8mb4比utf8更耗空间(注意区分)。
如果提供具体数据库类型(MySQL/PostgreSQL/SQLite)、业务场景(高并发?大数据量?)和当前瓶颈现象(CPU 满?IO 等待?),我可给出更精准的调参方案。
PHPWP博客