select语句必须带where条件以防全表扫描,实操中写完应立即检查;避免用!=或not in,字符串需加引号,日期比较宜用标准格式,join需明确关系,order by字段须建索引。

SELECT 语句怎么写才不会漏掉 WHERE 条件
不加 WHERE 的 SELECT 很容易查出全表数据,尤其在生产环境可能拖慢数据库、触发超时或被运维拦截。真正要用的查询几乎都带过滤条件。
实操建议:
- 写完
SELECT后,立刻检查是否跟了WHERE;没明确业务需求要查全部,就别省略 -
WHERE中避免用!=或NOT IN处理大表——它们很难走索引,换成IN或范围条件更稳 - 字符串比较记得加引号:
WHERE status = 'active',写成status = active会报错或隐式转为 0 - 日期字段别直接比字符串:
created_at > '2024-01-01'可以,但created_at > '2024-01-01 00:00:00'更准,避免时区或格式隐式转换问题
JOIN 多表时为什么结果行数不对
常见现象是:预期查 10 条订单,结果返回 30 行——大概率是 JOIN 时没控制好关联关系,比如一个订单对应多个订单项,又没去重或聚合。
实操建议:
- 先确认主表和从表的「一对多」关系方向,再决定用
LEFT JOIN还是INNER JOIN - 如果只关心主表记录是否存在从表数据,用
EXISTS比JOIN更清晰、性能通常更好:WHERE EXISTS (SELECT 1 FROM order_items oi WHERE oi.order_id = o.id) - 需要统计从表数量?直接
COUNT()+GROUP BY 主表主键,别靠JOIN后数行数 - 用
SELECT *跟JOIN一起出现时,注意字段名冲突(比如两张表都有id),要么显式写字段名,要么加别名:o.id AS order_id
ORDER BY 和 LIMIT 怎么配合才安全
单独用 LIMIT 10 看似简单,但如果没配 ORDER BY,MySQL 返回顺序不保证;而用了 ORDER BY 却没建索引,大数据量下会触发 filesort,响应直线上升。
实操建议:
-
ORDER BY字段必须有索引支撑,尤其是组合排序:ORDER BY status, created_at DESC需要联合索引(status, created_at),反过来不行 - 分页慎用
LIMIT 10000, 20:偏移量越大越慢,改用游标方式(如记录上一页最后的created_at和id,下一页查WHERE created_at ) -
ORDER BY中别混用 ASC/DESC:ORDER BY a ASC, b DESC在 MySQL 8.0 前无法用到索引,统一方向更稳妥
LIKE 查询为什么慢得像卡住
LIKE '%keyword%' 几乎必然走全表扫描,哪怕字段上有索引也没用;而 LIKE 'keyword%' 才能用上索引前缀。
实操建议:
- 模糊搜索尽量左对齐:
WHERE name LIKE 'John%',避免开头用% - 真要前后模糊?考虑全文索引(
FULLTEXT)或引入 Elasticsearch,别硬扛 - 大小写敏感问题:默认
LIKE依赖字段 collation,utf8mb4_0900_as_cs是区分大小写的,测试时用SELECT 'A' LIKE 'a'快速验证 - 参数化查询中拼接
%要小心:WHERE name LIKE CONCAT('%', ?, '%'),别在应用层拼,防止 SQL 注入











