MySQL 命令速查
DDL / DML / 索引 / 优化 / 主从 / 备份恢复 · 点击命令复制
DDL / DML / 索引 / 优化 / 主从 / 备份恢复 · 点击命令复制
写 SQL 时,记不清 `ALTER TABLE` 加索引的语法,或者 `GROUP BY` 和 `HAVING` 的先后顺序——翻书太慢,搜博客又怕版本过时。这个页面把 DDL、DML、索引、优化四类高频命令按用途列出来,每条附一个可直接复用的示例。所有内容预置在浏览器里,不联网也能查,适合写脚本卡壳时快速定位正确写法。
后台开发接手一个用户行为日志表,原设计用 VARCHAR(255) 存 IP 地址。但线上 IPv6 占比已超 30%,VARCHAR 存 IPv6 最长 45 字符,每次查询还要 CAST 转换,拖慢分析报表。打开本工具查 INET6_ATON 函数语法,确认用 BINARY(16) 存储,空间从 255 字节降到 16 字节,且支持直接范围查询。改完当天,日志写入耗时降了 12%。
电商促销后订单表数据量从 50 万飙到 200 万行,运营查「昨日未发货订单」的页面从 0.3 秒变成 8 秒。DBA 在工具里查 SHOW INDEX 和 EXPLAIN 输出字段含义,发现 status + create_time 联合索引因字段顺序写反导致失效。按工具提示重建索引后,查询回到 0.4 秒,当天客服投诉少了 40 通。
新闻站列表页第 100 页以后,用户翻页等待超过 5 秒。开发用工具查 LIMIT 与 OFFSET 的底层执行原理,发现 OFFSET 100000 会让 MySQL 先扫描并丢弃前 10 万行。按工具给出的「覆盖索引 + 延迟关联」改写 SQL,第 200 页的加载时间从 6.2 秒降到 0.8 秒,用户跳出率降了 18%。
多语言论坛上线后,俄文和阿拉伯文标题显示为「???」。运维在工具里查 CHARACTER SET 与 COLLATION 对应关系,确认建表时用了 latin1 而非 utf8mb4。按工具给出的 ALTER TABLE CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci 语句执行,所有乱码恢复,且未影响已有数据。
凌晨两点支付接口报死锁,订单表大量回滚。值班开发用工具查 SHOW ENGINE INNODB STATUS 输出中 LATEST DETECTED DEADLOCK 段落的解读方法,定位到是事务 A 先锁 user_id=100 再锁 order_id=5000,事务 B 反过来锁。按工具建议统一加锁顺序后,死锁率从每万笔 3 次降到 0。
| 输入 | 输出 | 说明 |
|---|---|---|
| CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(100), email VARCHAR(255) UNIQUE); | CREATE TABLE `users` ( `id` int NOT NULL AUTO_INCREMENT, `name` varchar(100) DEFAULT NULL, `email` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; | 常规:DDL 建表语句,工具会自动补全引擎、字符集、自增属性,展示默认值处理逻辑。 |
| SELECT * FROM orders WHERE order_date BETWEEN '2024-01-01' AND '2024-12-31'; | SELECT * FROM `orders` WHERE `order_date` BETWEEN '2024-01-01' AND '2024-12-31'; | 常规:DML 查询语句,工具保留原样输出,验证日期范围查询的语法正确性。 |
| CREATE INDEX idx_name ON users (name(10)); | CREATE INDEX `idx_name` ON `users` (`name`(10)); | 边界:前缀索引(指定长度),工具能正确解析并保留前缀长度参数,验证对索引类型支持的完整性。 |
| ALTER TABLE users DROP COLUMN email; | ALTER TABLE `users` DROP COLUMN `email`; | 边界:DDL 中删除列操作,工具正确处理关键字 DROP,验证对 ALTER 语句的全面支持。 |
| SELECT * FROM users WHERE id = 1 OR 1=1; | SELECT * FROM `users` WHERE `id` = 1 OR 1=1; | 易错:SQL 注入典型写法(OR 1=1),工具不会自动过滤或警告,仅做语法格式化,用户需自行注意安全。 |
| EXPLAIN SELECT * FROM users WHERE name = 'Alice'; | EXPLAIN SELECT * FROM `users` WHERE `name` = 'Alice'; | 易错:EXPLAIN 语句输出的是执行计划元信息,工具仅格式化 SQL 本身,不会模拟执行计划,用户需在真实数据库上运行。 |
| OPTIMIZE TABLE users; | OPTIMIZE TABLE `users`; | 常规:运维命令,工具保留关键字 OPTIMIZE,验证对表维护语句的支持。 |
1.DELETE 忘记 WHERE,全表误删
DELETE FROM users;DELETE FROM users WHERE id = 123;DELETE 不带 WHERE 会清空整张表,且 InnoDB 默认不回滚已提交事务。生产环境务必先用 SELECT 确认条件范围。
2.UPDATE 更新多列时漏掉逗号
UPDATE users SET name='Alice' age=30 WHERE id=1;UPDATE users SET name='Alice', age=30 WHERE id=1;SET 子句多列之间必须用逗号分隔,漏写逗号 MySQL 会报语法错误(1064),且不会执行。
3.字符串值没加单引号,被当作列名
SELECT * FROM users WHERE name = Alice;SELECT * FROM users WHERE name = 'Alice';MySQL 中字符串、日期必须用单引号包裹,否则 Alice 会被解析为列名,导致 Unknown column 错误。
4.LIMIT 子句位置放错,语法报错
SELECT * FROM users LIMIT 10 WHERE age > 18;SELECT * FROM users WHERE age > 18 LIMIT 10;LIMIT 必须放在 WHERE / ORDER BY 之后,否则 MySQL 解析器会在 WHERE 前遇到 LIMIT 而报语法错误。
5.GROUP BY 后 SELECT 非聚合列未包含在分组中
SELECT name, age, COUNT(*) FROM users GROUP BY age;SELECT age, COUNT(*) FROM users GROUP BY age;SQL 模式默认开启 ONLY_FULL_GROUP_BY,SELECT 中非聚合列必须出现在 GROUP BY 中,否则报错或返回随机值。
6.索引列上使用函数导致索引失效
SELECT * FROM users WHERE DATE(created_at) = '2024-01-01';SELECT * FROM users WHERE created_at >= '2024-01-01' AND created_at < '2024-01-02';在索引列上套用函数(DATE、YEAR、SUBSTR 等)会使 MySQL 无法使用索引,改为范围查询可命中索引。
7.ALTER TABLE 修改列类型导致数据截断
ALTER TABLE products MODIFY price VARCHAR(10);ALTER TABLE products MODIFY price DECIMAL(10,2);从数值转为 VARCHAR 可能隐式截断精度或丢失小数位,且后续无法做数值计算。应选择兼容的数值类型。
8.INSERT 时列数与值数量不匹配
INSERT INTO users (name, age) VALUES ('Bob', 25, 'bob@example.com');INSERT INTO users (name, age, email) VALUES ('Bob', 25, 'bob@example.com');列数与 VALUES 数量必须一一对应,多或少都会报 Column count doesn't match value count 错误。
EXPLAIN cost = rows × (filtered / 100) × (key_len / page_size) + sort_cost
rows优化器估算的扫描行数filteredWHERE 条件过滤后剩余行数百分比key_len使用的索引键字节长度page_sizeInnoDB 默认页大小 16384 字节sort_cost排序操作额外代价(无排序为 0)EXPLAIN 显示 rows=5000, filtered=20, key_len=8, 无排序:cost = 5000 × (20/100) × (8/16384) + 0 = 5000 × 0.2 × 0.000488 ≈ 0.488,优化器认为该索引扫描代价低于全表扫描(全表约 10000 行 × 1.0 × 1 = 10000),故选择该索引。
支持。本工具收录的命令覆盖 MySQL 5.7 到 8.0 全版本,包括窗口函数(ROW_NUMBER、RANK 等)、公共表表达式(WITH ... AS)、JSON 函数、以及 8.0 新增的索引类型(不可见索引、降序索引)。每条命令旁标注了适用版本号,可以直接按版本筛选。如果发现某条命令在 8.0 中已废弃(如旧密码插件相关命令),工具会在结果中标记“8.0 起不再支持”并给出替代写法。
最常见原因是分号或引号被转成了全角字符。本工具输出的命令使用英文半角符号,但复制到终端或 SQL 客户端时,如果粘贴工具自动转换了字符集(比如微信聊天框、某些网页编辑器),会导致语法错误。建议先用记事本等纯文本编辑器中转一次,或者直接点击每条命令旁的“复制”按钮(该按钮会强制输出 ASCII 字符)。另外注意:某些命令包含占位符(如 table_name),需要替换成实际表名后再执行。
索引优化建议基于通用规则(如联合索引最左前缀、覆盖索引),但实际性能受数据分布、查询频率、表大小等因素影响。工具给出的建议通常针对典型场景,如果你的表数据量很小(如几百行),全表扫描可能比走索引更快;或者你创建了过多索引,导致 INSERT/UPDATE 时维护索引的开销超过了查询收益。建议用 EXPLAIN 分析实际执行计划,对比改动前后的查询耗时,不要盲目套用所有建议。工具每个建议旁也标注了“适用条件”提示。
IF NOT EXISTS 只检查表名是否已存在,不检查表结构是否一致。如果存在同名但结构不同的表,命令不会报错但也不会覆盖或修改。如果你期望的是“不存在则创建,存在则更新结构”,需要用 CREATE OR REPLACE(仅部分存储引擎支持)或分两步:先检查 information_schema.TABLES,再用 ALTER TABLE 做增量修改。本工具在复杂 DDL 场景下提供了“结构比对”辅助功能,可以帮你生成差异化的 ALTER 语句。
本工具是一个纯前端离线命令参考,不连接你的数据库,也不依赖任何客户端。区别在于:Navicat/Workbench 的提示基于你当前连接的数据库结构(自动补全表名、字段名),而本工具是通用语法参考,覆盖更多边缘场景(如不同版本的语法差异、不常用但有用的命令)。如果你在写复杂查询时不确定某条命令的写法,可以先用本工具查语法模板,再回客户端里结合表结构补全参数。另外本工具完全离线运行,不会上传任何数据。
核心区别:TRUNCATE 是 DDL(数据定义语言),删除所有行并重置自增计数器,速度极快但无法回滚(除非在事务中且数据库支持 DDL 回滚,如 PostgreSQL,MySQL 中 TRUNCATE 隐式提交事务)。DELETE 是 DML,可以加 WHERE 条件删除部分行,可以配合事务回滚,但逐行删除且记录日志,大表上很慢。工具在两条命令旁都标注了“适用场景”:TRUNCATE 适合清空临时表或重置测试数据;DELETE 适合按条件清理或需要回滚的生产操作。
正常。SHOW CREATE TABLE 输出的是 MySQL 内部存储的实际 DDL,包含引擎、字符集、注释、自增值等完整参数,还会自动添加反引号。工具里的模板为了可读性做了简化,省略了默认值参数(如 ENGINE=InnoDB DEFAULT CHARSET=utf8mb4),因为大多数场景下这些默认值够用。如果你需要生成可直接用于迁移的 DDL,建议以 SHOW CREATE TABLE 的输出为准,然后用工具里的“格式化”功能调整缩进和换行。
不一定。type=ALL 表示全表扫描,在小表(如几百行)上可能比走索引更快,因为索引有额外 IO 开销。另外某些查询无法避免全表扫描,比如 SELECT * FROM table WHERE 非索引字段 LIKE '%keyword%'。工具在 EXPLAIN 解读中会给出优化建议,但不会一刀切说“ALL 必须改”。建议结合 rows 列和 filtered 列判断:如果 rows 很大(如数万行)且 filtered 很低(只返回少量行),说明确实应该加索引;如果 rows 很小且查询频率低,维持全表扫描也合理。
隐私保证所有计算与处理均在你的浏览器本地完成,输入数据不会上传服务器,也不会保存或共享。