以下是高级SQL技巧的深度解析,涵盖复杂查询优化、分析函数应用和架构设计实践,结合主流数据库(MySQL/PostgreSQL/Oracle)的实战示例:
一、窗口函数(Window Functions)进阶
- 排名与分页
sql
复制
– 获取部门薪资排名前三的员工(含并列)
SELECT
employee_id,
name,
salary,
DENSE_RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rank
FROM employees
QUALIFY rank <= 3; – PostgreSQL使用CTE过滤,MySQL需嵌套查询
– 分页查询优化(避免OFFSET性能问题)
SELECT *
FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY create_time) AS rn
FROM orders) t
WHERE rn BETWEEN 1001 AND 1020; – 替代LIMIT 1000,20
2. 滑动窗口聚合
sql
复制
– 计算最近7天滚动平均销售额
SELECT
order_date,
AVG(amount) OVER (
ORDER BY order_date
RANGE BETWEEN INTERVAL ‘6’ DAY PRECEDING AND CURRENT ROW
) AS 7d_avg
FROM daily_sales;
– 累计求和(部门内按时间累计)
SELECT
dept_id,
sale_date,
SUM(amount) OVER (
PARTITION BY dept_id
ORDER BY sale_date
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
) AS running_total
FROM sales;
二、高级关联与数据重组
- 递归CTE(处理层次结构)
sql
复制
– 查询组织架构树(向下递归)
WITH RECURSIVE org_tree AS (
SELECT id, name, parent_id, 1 AS level
FROM departments
WHERE parent_id IS NULL – 根节点
UNION ALL
SELECT d.id, d.name, d.parent_id, ot.level + 1
FROM departments d
JOIN org_tree ot ON d.parent_id = ot.id
)
SELECT * FROM org_tree;
– 路径枚举(向上递归)
WITH RECURSIVE path_cte AS (
SELECT id, name, CAST(name AS VARCHAR(1000)) AS path
FROM employees WHERE manager_id IS NULL
UNION ALL
SELECT e.id, e.name, CONCAT(pc.path, ’ > ', e.name)
FROM employees e
JOIN path_cte pc ON e.manager_id = pc.id
)
SELECT * FROM path_cte;
2. 横向关联(LATERAL JOIN)
postgresql
复制
– 为每个用户获取最近3笔订单
SELECT u.user_id, o.order_id, o.amount
FROM users u
CROSS JOIN LATERAL (
SELECT *
FROM orders
WHERE user_id = u.user_id
ORDER BY order_date DESC
LIMIT 3
) o;
三、性能优化核心策略
- 执行计划分析
sql
复制
– MySQL
EXPLAIN ANALYZE
SELECT /*+ MAX_EXECUTION_TIME(1000) */ *
FROM large_table WHERE status = ‘active’;
– PostgreSQL
SET enable_seqscan = off; – 强制索引扫描测试
EXPLAIN (ANALYZE, BUFFERS)
SELECT * FROM orders WHERE total > 1000;
2. 索引优化技巧
覆盖索引:包含查询所需全部字段
sql
复制
CREATE INDEX idx_cover ON orders (user_id) INCLUDE (total, status);
函数索引:处理表达式查询
sql
复制
CREATE INDEX idx_lower_name ON users (LOWER(name));
分区表索引:本地索引优于全局索引
sql
复制
CREATE TABLE sales (
sale_date DATE,
region VARCHAR(20)
PARTITION BY RANGE (sale_date);
CREATE INDEX idx_local ON sales(region) LOCAL;
四、高级数据处理技巧
- 数据透视(PIVOT)
sql
复制
– PostgreSQL crosstab扩展
SELECT *
FROM crosstab(
‘SELECT department, job_role, AVG(salary)
FROM employees
GROUP BY 1,2
ORDER BY 1,2’,
‘SELECT DISTINCT job_role FROM employees’
) AS final_result(dept VARCHAR, engineer NUMERIC, manager NUMERIC); - JSON数据处理
sql
复制
– MySQL JSON路径查询
SELECT
user_id,
JSON_EXTRACT(profile, ‘ . a d d r e s s . c i t y ′ ) A S c i t y , J S O N C O N T A I N S ( i n t e r e s t s , ′ " r e a d i n g " ′ ) A S l i k e s r e a d i n g F R O M u s e r s W H E R E J S O N V A L U E ( p r o f i l e , ′ .address.city') AS city, JSON_CONTAINS(interests, '"reading"') AS likes_reading FROM users WHERE JSON_VALUE(profile, ' .address.city′)AScity,JSONCONTAINS(interests,′"reading"′)ASlikesreadingFROMusersWHEREJSONVALUE(profile,′.age’) > 25;
– PostgreSQL JSONB索引优化
CREATE INDEX idx_gin_profile ON users USING GIN (profile_jsonb);
五、事务与并发控制
- 悲观锁实践
sql
复制
BEGIN;
SELECT * FROM inventory
WHERE product_id = 123
FOR UPDATE SKIP LOCKED; – 跳过被锁定的行
UPDATE inventory SET stock = stock - 1 WHERE product_id = 123;
COMMIT; - 乐观锁实现
sql
复制
UPDATE products
SET stock = stock - 1, version = version + 1
WHERE id = 456 AND version = 5; – 应用层检查影响行数
六、高级SQL特性应用
- MERGE语句(UPSERT)
sql
复制
– Oracle/SQL Server
MERGE INTO employees t
USING (SELECT 101 AS id, ‘Alice’ AS name FROM dual) s
ON (t.id = s.id)
WHEN MATCHED THEN
UPDATE SET t.name = s.name
WHEN NOT MATCHED THEN
INSERT (id, name) VALUES (s.id, s.name); - 动态SQL(防止注入)
sql
复制
– PostgreSQL EXECUTE
EXECUTE format(‘SELECT * FROM %I WHERE id = $1’, ‘users’) USING 123;
– MySQL预处理语句
PREPARE stmt FROM ‘SELECT * FROM products WHERE category = ?’;
SET @category = ‘electronics’;
EXECUTE stmt USING @category;
七、数据库设计进阶
- 范式与反范式平衡
垂直分片:将大表按列拆分到不同物理表
汇总表:预计算常用聚合指标(如每日销售额)
归档策略:使用分区表隔离热数据与历史数据
- 扩展模式设计
sql
复制
– 事件溯源模式
CREATE TABLE account_events (
event_id UUID PRIMARY KEY,
account_id INT,
event_type VARCHAR(20),
event_data JSONB,
created_at TIMESTAMPTZ DEFAULT NOW()
);
– 软删除模式
ALTER TABLE users
ADD COLUMN is_deleted BOOLEAN DEFAULT false,
ADD COLUMN deleted_at TIMESTAMPTZ;
总结
掌握高级SQL需聚焦三个维度:
复杂逻辑实现:窗口函数、递归CTE、JSON处理扩展数据操作边界
性能深层优化:执行计划解读、索引策略、分区表设计提升海量数据查询效率
架构级SQL应用:通过MERGE、动态SQL等实现业务逻辑的数据库原生表达
建议结合具体数据库文档(如MySQL 8.0 Window Functions)进行专项训练,同时使用EXPLAIN分析工具持续优化关键查询。