管理杂谈OA答疑ERP答疑教程搜索

8 个最容易写错的 SQL 习惯,正在拖慢并毁掉你的数据库


很多数据库问题,并不是“高并发架构”这种听起来很吓人的大场面搞出来的。

真正把库拖慢、把业务搞崩、把同事逼疯的,往往是一些看起来没什么问题、实际上非常致命的 SQL 习惯

这些写法在测试环境里也许还能跑,在数据量小的时候也许没感觉,但一旦表变大、业务变复杂、并发上来,代价就会立刻显现:慢查询、锁表、索引失效、脏数据、误删、甚至直接事故

今天就来聊 8 个最常见、也最容易被忽视的坏习惯。

如果你平时写 SQL,这篇建议你对照着自查一遍。


1. 张口就是 SELECT *

这是最常见的“偷懒型写法”。

SELECT *
FROM
 orders
WHERE
 user_id = 1001;

看上去很方便,但问题不少:

更稳妥的写法是:只查你真正需要的字段。

SELECT order_id, order_no, total_amount, created_at
FROM
 orders
WHERE
 user_id = 1001;

为什么这件事很重要?

因为数据库的性能问题,很多时候不是“算得太慢”,而是“搬得太多”。

你以为自己只是多拿了几列,数据库看到的是:

一句话: 是小项目的朋友,大表时代的敌人。


2. WHERE 条件对字段做函数运算

很多人写条件时,喜欢直接对列做处理:

SELECT *
FROM
 orders
WHERE
 DATE(created_at) = '2026-03-26';

这类写法语义上没错,但性能上很容易出事。

因为当你对索引列做函数计算时,数据库往往没法直接利用索引,最后就可能退化成全表扫描。

更好的写法是改成范围查询:

SELECT order_id, user_id, created_at
FROM
 orders
WHERE
 created_at >= '2026-03-26 00:00:00'
  AND
 created_at <  '2026-03-27 00:00:00';

记住一个简单原则

尽量别动列,去动常量。

也就是说,别让数据库先把每一行都加工一遍,再比较;而是把边界算好,直接去命中索引。

这类错误在以下场景尤其常见:

看着优雅,跑起来经常像灾难片。


3. 模糊查询一上来就是前缀 %

比如:

SELECT *
FROM
 users
WHERE
 name LIKE '%周%';

这类查询在搜索场景很常见,但一旦前面加了 %,普通索引通常就很难用了。

结果就是:扫全表,然后一行一行比。

如果你的表有几百万数据,这种写法就不再是“能跑”,而是“谁写的,出来挨打”。

怎么改?

要看业务目标:

情况一:前缀匹配

SELECT user_id, name
FROM
 users
WHERE
 name LIKE '周%';

这种更有机会走索引。

情况二:全文搜索需求

如果你真的是要“包含某关键词”,别硬拿普通 LIKE '%xxx%' 扛所有搜索需求。

更合理的方向通常是:

数据库不是不能搜,但你别拿它当全文检索引擎往死里打。


4. INOR、联表条件乱写,结果把执行计划写崩了

很多 SQL 慢,不是因为数据库不够强,而是因为你把优化器逼疯了。

例如:

SELECT *
FROM
 orders
WHERE
 status = 'PAID'
   OR
 user_id = 1001;

再比如:

SELECT *
FROM
 orders
WHERE
 id IN (1,2,3,4,5,...一大串...);

或者联表时条件不清晰:

SELECT *
FROM
 orders o
JOIN
 users u ON o.user_id = u.id
WHERE
 o.created_at >= '2026-01-01';

表面看都合法,实际上可能导致:

更靠谱的思路

例如把 OR 拆开:

SELECT order_id, user_id, status
FROM
 orders
WHERE
 status = 'PAID'

UNION
 ALL

SELECT
 order_id, user_id, status
FROM
 orders
WHERE
 user_id = 1001
  AND
 status <> 'PAID';

不一定每次都要这么写,但你至少得知道:

复杂条件不是不能写,而是不能闭着眼乱写。


5. 分页永远只会写 LIMIT 100000, 20

这也是经典事故现场。

SELECT *
FROM
 orders
ORDER
 BY id
LIMIT 100000, 20;

在前期数据少的时候没什么感觉,数据一多就开始痛了。

原因很简单:数据库不是直接跳到第 100000 行给你拿 20 条,它通常需要先扫描/排序前面大量记录,再丢掉它们

页码越深,越慢。

更好的方式:游标分页 / 基于最后一条记录翻页

SELECT order_id, id, created_at
FROM
 orders
WHERE
 id > 100000
ORDER
 BY id
LIMIT 20;

如果按时间 + ID 排序,也可以这样:

SELECT order_id, created_at
FROM
 orders
WHERE
 (created_at, id) > ('2026-03-26 08:00:00', 100000)
ORDER
 BY created_at, id
LIMIT 20;

什么时候还能用 offset 分页?

可以,但要有边界:

一旦是开放式列表、大数据量、用户不断下拉,继续死磕深分页,就是在给数据库加班。


6. UPDATE / DELETE 不带条件,或者条件写得过于自信

这个不用解释太多,懂的都疼。

DELETE FROM orders;

或者:

UPDATE users
SET
 status = 'inactive';

有些人会说:“我不是不加条件,我只是条件写错了。”

那效果也没什么本质区别。

更稳的操作习惯

先查再改

SELECT *
FROM
 users
WHERE
 last_login_at < '2025-01-01';

确认影响范围没问题,再执行:

UPDATE users
SET
 status = 'inactive'
WHERE
 last_login_at < '2025-01-01';

先加 LIMIT(适用于支持的场景)

DELETE FROM logs
WHERE
 created_at < '2024-01-01'
LIMIT 1000;

在事务里执行,并先备份关键数据

尤其是生产环境,别把自己当赌神。

一个建议,虽然朴素但管用

凡是会改数据的 SQL,执行前都问自己一句:

“如果我这句条件写错了,最坏会死多少数据?”

你会立刻冷静很多。


7. 觉得“有索引就一定快”,结果建了一堆废索引

不少团队一遇到慢 SQL,就开始下意识加索引。

这思路和“头疼就把头砍了”差不多,主打一个直接。

问题是,索引不是免费午餐。

索引会带来:

例如下面这种:

很多时候你以为自己很细致,实际上是在堆垃圾。

正确姿势是什么?

一句话:

索引是手术刀,不是护身符。


8. 不看执行计划,纯靠玄学调 SQL

这是最致命的习惯。

很多人优化 SQL 的方式是这样的:

问题是,数据库不看你的感觉,只看执行计划。

优化 SQL,至少先看这些

以 MySQL 为例,先跑:

EXPLAIN
SELECT
 order_id, user_id, total_amount
FROM
 orders
WHERE
 user_id = 1001
  AND
 created_at >= '2026-03-01 00:00:00';

重点关注:

如果连执行计划都不看,就开始“优化”,那基本等于:

闭着眼给数据库做手术。

勇气可嘉,结果一般不太行。


最后总结:真正毁库的,往往不是复杂 SQL,而是习惯性随手一写

把今天这 8 条收一下:

  1. 1. SELECT * 随手乱用
  2. 2. 在索引列上做函数运算
  3. 3. 模糊查询前缀直接 %
  4. 4. OR / IN / 联表条件乱写
  5. 5. 深分页只会用 LIMIT offset, size
  6. 6. UPDATE / DELETE 过于自信
  7. 7. 乱加索引,把数据库当收纳箱
  8. 8. 不看执行计划,靠玄学调优

这些问题有一个共同点:

平时不痛,一出事就很痛。

而且最可怕的是,它们几乎都不是“不会 SQL”造成的,反而经常出现在“会一点、写得很顺手”的阶段。

真正靠谱的 SQL 开发习惯,不是能把语法写对,而是:

阅读原文:原文链接


更多精彩文章浏览...
点击右上角图标分享到朋友圈
官方网站:http://www.clicksun.cn
咨询热线:400-186-1886
服务邮箱:service@clicksun.cn