深夜改完最后一行SQL,窗外路灯都熄了。屏幕右下角弹出内存不足的警告,查询跑了半小时还没结果。
这种憋屈我经历过太多次。作为和数据库打了十年交道的程序员,有些技巧教科书不会教,但能让你少掉一半头发。
1. 用CTE代替嵌套地狱
-- 传统嵌套写法(晕眩警告)
SELECT *
FROM (
SELECT *
FROM (
SELECT user_id, MAX(order_date)
FROM orders
GROUP BY user_id
) t1
JOIN users ON t1.user_id = users.id
) t2 WHERE ...
-- CTE清爽版
WITH latest_orders AS (
SELECT user_id, MAX(order_date) AS last_order
FROM orders
GROUP BY user_id
)
SELECT users.*, last_order
FROM users
JOIN latest_orders ON users.id = latest_orders.user_id
当嵌套超过三层,代码就成迷宫了。CTE像给查询搭脚手架,先拆解再组装。有次我重构了同事12层嵌套的报表,运行时间从47秒降到3秒。
2. 窗口函数救场王
-- 找出每个部门工资前三的员工
SELECT department, employee, salary
FROM (
SELECT *,
DENSE_RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS rank
FROM employees
) tmp
WHERE rank <= 3
以前要写复杂自连接才能实现分组排名,现在三行搞定。
更妙的是 LEAD()/ LAG()能直接抓取相邻行数据,做环比分析时特别救命。
3. CASE表达式化腐朽为神奇
-- 动态打标签
SELECT order_id,
CASE
WHEN amount > 1000 THEN '大客户'
WHEN amount > 500 AND create_time > '2025-01-01' THEN '新锐客户'
ELSE '普通客户'
END AS customer_type
FROM orders
比在代码里写if-else链高效得多。
有次运营临时要分十级用户标签,我用CASE表达式半小时搞定,Java组同事还在改代码。
4. 临时表破性能瓶颈
-- 复杂查询分步走
CREATE TEMP TABLE user_summary AS
SELECT user_id, SUM(amount) AS total_spend
FROM orders
GROUP BY user_id;
-- 后续查询复用
SELECT u.name, us.total_spend
FROM users u
JOIN user_summary us ON u.id = us.user_id
WHERE ...;
当多表关联查询超时,把中间结果存临时表往往有奇效。
处理千万级数据关联,拆成三个临时表后,查询从15分钟降到40秒。
5. EXISTS比IN更敏捷
-- 查有订单的用户
SELECT *
FROM users u
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.user_id = u.id
);
当 IN子查询结果集很大时,数据库可能全表扫描。
EXISTS只要找到一条匹配就停止。实测在百万级数据中,速度能快5-8倍。
6. 别让SELECT *毁了索引
-- 坏习惯
SELECT * FROM products WHERE category = 'electronics';
-- 正确姿势
SELECT id, name, price
FROM products
WHERE category = 'electronics';
多查一个字段可能就让索引失效。
有次线上查询突然变慢,发现是有人加了 description字段。只取必要字段,是对数据库最基本的温柔。
7. 日期处理避开暗坑
-- 获取上周一(跨年也不怕)
SELECT DATE_TRUNC('week', CURRENT_DATE) - INTERVAL '7 days';
-- 计算工作日(排除周末)
SELECT COUNT(*)
FROM generate_series('2025-10-01', '2025-10-17', '1 day')
WHERE EXTRACT(DOW FROM generate_series) NOT IN (0,6);
日期函数是SQL里最易踩坑的。曾因忘记时区转换,导致跨时区报表差8小时。
现在所有时间字段都存UTC,展示时再转换。
这些技巧没有高深理论,全是实战中摔出来的经验。
刚工作时我总追求写"聪明"的复杂查询,现在才懂:
好SQL的标准是三个月后自己还能看懂。
更新时间:2025-10-19
本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828
© CopyRight 2020-=date("Y",time());?> All Rights Reserved. Powered By 61893.com 闽ICP备11008920号
闽公网安备35020302035593号