本文整合了 MySQL 数据库的常用命令、性能优化技巧和常见问题解决方案。
常用命令
创建 UTF-8 数据库
1 2 3 4 5
| CREATE DATABASE `mydb` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE DATABASE `mydb` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
|
UPDATE JOIN 技巧
使用 JOIN 进行批量更新:
1 2 3 4 5 6 7 8 9 10 11
| UPDATE train AS a, train AS b SET a.next_temp = b.temp WHERE b.timestamp = DATE_ADD(a.timestamp, INTERVAL 30 MINUTE);
UPDATE amdashboard a, ASCNCOAClean b SET a.ASCID = b.id, a.ASCFirst = b.firstname, a.ASCLast = b.lastname WHERE a.actorsfirst = b.firstname;
|
复制表
1 2 3 4 5
| CREATE TABLE newtable LIKE oldtable;
INSERT newtable SELECT * FROM oldtable;
|
大小写问题
在 Linux 和 Windows 上,MySQL 对表名大小写的处理不同,这可能导致跨平台问题。
大小写规则
| 对象 |
Linux |
Windows |
| 数据库名 |
区分大小写 |
不区分 |
| 表名 |
区分大小写 |
不区分 |
| 列名/别名 |
不区分 |
不区分 |
| 变量名 |
区分大小写 |
区分大小写 |
解决方案
让 MySQL 不区分表名大小写:
1 2 3 4 5 6 7 8
| sudo vim /etc/my.cnf
lower_case_table_names = 1
sudo systemctl restart mysql
|
注意:此设置需要在数据库初始化前配置,已有数据的情况下修改可能导致问题。
性能优化
存储引擎选择
| 引擎 |
适用场景 |
特点 |
| InnoDB |
事务处理、高并发 |
支持事务、行级锁、外键 |
| MyISAM |
读密集、全文搜索 |
表级锁、查询速度快 |
1 2 3 4 5
| SHOW VARIABLES LIKE '%storage_engine%';
SHOW ENGINES;
|
查询缓存优化
对于重复查询,利用缓存可以显著提升性能。但要避免使用会导致缓存失效的函数:
1 2 3 4 5 6
| SELECT * FROM users WHERE created_at > NOW(); SELECT * FROM orders ORDER BY RAND() LIMIT 10;
SELECT * FROM users WHERE created_at > '2024-01-01';
|
索引优化
为经常用于搜索、排序、连接的字段建立索引:
1 2 3 4 5
| CREATE INDEX idx_username ON users(username);
CREATE INDEX idx_name_date ON orders(customer_name, order_date);
|
垂直分割
将不常用的大字段分离到单独的表:
注意:分割后避免频繁 JOIN,否则性能反而下降。
大型操作处理
拆分大型 DELETE/INSERT,避免长时间锁表:
1 2 3 4 5 6
| DELETE FROM logs WHERE created_at < '2023-01-01';
DELETE FROM logs WHERE created_at < '2023-01-01' LIMIT 10000;
|
避免性能陷阱
| 陷阱 |
问题 |
建议 |
SELECT * |
读取不必要的字段 |
明确指定需要的字段 |
ORDER BY RAND() |
全表扫描后排序 |
使用其他随机算法 |
缺少 LIMIT |
返回过多数据 |
单条查询加 LIMIT 1 |
使用 NULL |
额外的比较开销 |
尽可能使用 NOT NULL |
查看表大小
基本查询
1 2 3 4 5
| USE information_schema;
SELECT table_name, table_rows, data_length + index_length AS total_size FROM tables WHERE table_schema = 'your_database';
|
详细查询(格式化输出)
1 2 3 4 5 6 7 8 9
| SELECT CONCAT(table_schema, '.', table_name) AS 'Table Name', CONCAT(ROUND(table_rows / 1000000, 4), 'M') AS 'Number of Rows', CONCAT(ROUND(data_length / (1024 * 1024 * 1024), 4), 'G') AS 'Data Size', CONCAT(ROUND(index_length / (1024 * 1024 * 1024), 4), 'G') AS 'Index Size', CONCAT(ROUND((data_length + index_length) / (1024 * 1024 * 1024), 4), 'G') AS 'Total' FROM information_schema.TABLES WHERE table_schema = 'your_database' ORDER BY (data_length + index_length) DESC;
|
常见问题解决
#1071 - Key too long 错误
当索引键长度超过限制时会报此错误:
1 2 3 4 5
| SET @@global.innodb_large_prefix = 1;
CREATE INDEX idx_name ON users(name(191));
|
时间段查询
查询某个时间点前 30 分钟的数据:
1 2 3 4 5 6
| SELECT * FROM tb WHERE col1 < DATE_ADD(NOW(), INTERVAL -30 MINUTE);
SELECT * FROM tablename WHERE column_date >= CURRENT_TIMESTAMP - INTERVAL 30 MINUTE;
|
生成随机数
1 2
| SELECT ROUND(RAND() * 100, 2);
|
用户登录问题
新建用户无法本地登录时,检查是否存在匿名用户:
1 2 3 4 5 6 7 8 9 10
| SELECT host, user, password FROM mysql.user;
DELETE FROM mysql.user WHERE user = '' AND host = 'localhost'; FLUSH PRIVILEGES;
GRANT SELECT, INSERT, UPDATE, DELETE ON test.* TO appadmin@'localhost' IDENTIFIED BY 'password';
|
root 密码和远程访问
1 2 3 4 5
| GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'your_password' WITH GRANT OPTION;
FLUSH PRIVILEGES;
|
参考链接