name: sql-pro description: 当用户需要SQL开发、数据库设计、查询优化、性能调优或跨PostgreSQL、MySQL、SQL Server、Oracle平台的数据库管理时使用。
SQL专家
目的
提供跨主流数据库平台(PostgreSQL、MySQL、SQL Server、Oracle)的专家级SQL开发能力,专精于复杂查询设计、性能优化和数据库架构。精通ANSI SQL标准、平台特定优化和现代数据模式,专注于效率和可扩展性。
何时使用
- 编写包含连接、CTE、窗口函数或递归查询的复杂SQL查询
- 为新应用设计数据库模式或重构现有模式
- 通过执行计划分析优化慢速SQL查询
- 在不同数据库平台间进行数据迁移(MySQL → PostgreSQL)
- 实现存储过程、函数或触发器
- 使用高级聚合和窗口函数构建分析报告
- 将业务需求转化为SQL查询逻辑
- 跨平台SQL兼容性问题(不同方言)
快速开始
在以下情况调用此技能:
- 编写使用CTE、窗口函数或递归模式的复杂查询
- 设计或重构数据库模式
- 通过执行计划分析优化慢速查询
- 在不同数据库平台间迁移数据
- 实现存储过程、函数或触发器
- 使用高级聚合构建分析报告
在以下情况不要调用:
- 需要PostgreSQL特定功能 → 使用 postgres-pro
- MySQL特定管理 → 使用 database-administrator
- 简单的CRUD操作 → 使用 backend-developer
- ORM查询模式 → 使用相应的语言技能
决策框架
CTE vs 子查询 vs JOIN 决策树
查询需求分析
│
├─ 需要多次引用结果吗?
│ └─ 是 → 使用CTE(避免重复子查询评估)
│ WITH user_totals AS (SELECT ...)
│ SELECT * FROM user_totals WHERE ...
│ UNION ALL
│ SELECT * FROM user_totals WHERE ...
│
├─ 递归数据遍历(层次结构、图)?
│ └─ 是 → 使用递归CTE(递归的唯一选项)
│ WITH RECURSIVE tree AS (
│ SELECT ... -- 锚点
│ UNION ALL
│ SELECT ... FROM tree ... -- 递归
│ )
│
├─ 简单查找或过滤?
│ └─ 使用JOIN(查询计划器最可优化)
│ SELECT u.*, o.total
│ FROM users u
│ JOIN orders o ON u.id = o.user_id
│
├─ WHERE子句中的相关子查询?
│ ├─ 检查存在性 → 使用EXISTS(在首次匹配时停止)
│ │ WHERE EXISTS (SELECT 1 FROM orders WHERE user_id = u.id)
│ │
│ └─ 值比较 → 改用JOIN
│ -- 差: WHERE (SELECT COUNT(*) FROM orders WHERE user_id = users.id) > 5
│ -- 好: JOIN (SELECT user_id, COUNT(*) as cnt FROM orders GROUP BY user_id)
│
└─ 可读性与性能的权衡?
├─ 逻辑复杂,可读性关键 → CTE
│ (更易于理解、调试、维护)
│
└─ 性能关键,逻辑简单 → 子查询或JOIN
(查询计划器可以内联和优化)
窗口函数 vs GROUP BY 决策矩阵
| 需求 | 解决方案 | 示例 |
|---|---|---|
| 需要聚合 + 行级详细信息 | 窗口函数 | SELECT name, salary, AVG(salary) OVER () as avg_salary FROM employees |
| 仅需要聚合结果 | GROUP BY | SELECT dept, AVG(salary) FROM employees GROUP BY dept |
| 排名/行号 | 窗口函数 (ROW_NUMBER, RANK, DENSE_RANK) | ROW_NUMBER() OVER (ORDER BY sales DESC) |
| 累计总计 / 移动平均 | 带框架的窗口函数 | SUM(amount) OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) |
| LAG/LEAD(访问前/后行) | 窗口函数 | LAG(price, 1) OVER (ORDER BY date) as prev_price |
| 百分位数 / NTILE | 窗口函数 | NTILE(4) OVER (ORDER BY score) as quartile |
| 按组的简单计数/求和/平均 | GROUP BY(更高效) | SELECT category, COUNT(*) FROM products GROUP BY category |
危险信号 → 升级给Oracle
| 观察现象 | 为何升级 | 示例 |
|---|---|---|
| 执行计划中的笛卡尔积 | 意外的交叉连接导致指数级行数 | “查询返回数百万行” |
| 复杂多级递归CTE性能问题 | 需要高级优化 | “递归CTE遍历10+级别,包含10万个节点” |
| 具有不兼容功能的跨平台迁移 | 平台特定功能映射 | “将Oracle CONNECT BY迁移到PostgreSQL递归CTE” |
| 包含10+个连接和复杂逻辑的查询 | 架构异味,可能需要重新设计 | “连接15个表的单个查询” |
| 具有复杂时间序列逻辑的时间查询 | 高级分析模式 | “具有历史快照的SCD类型2” |
核心能力
高级查询模式
- 公共表表达式(CTE)和递归查询
- 窗口函数:ROW_NUMBER, RANK, LEAD, LAG, 聚合窗口
- 用于数据转换的PIVOT/UNPIVOT操作
- 用于树/图结构的层次查询
- 用于基于时间分析的时间查询
查询优化
- 执行计划分析和解释
- 索引选择策略和覆盖索引
- 统计信息管理和维护
- 查询提示和计划指南(必要时)
- 并行查询执行调优
索引设计模式
- 聚集索引与非聚集索引
- 用于查询优化的覆盖索引
- 用于选择性查询的过滤/部分索引
- 基于函数/表达式的索引
- 复合索引列排序
质量检查清单
查询性能:
- [ ] 执行时间满足要求(OLTP: <100ms, 分析: <5s)
- [ ] 所有复杂查询都审查了EXPLAIN ANALYZE
- [ ] 大表上没有顺序扫描(除非有意为之)
- [ ] 索引有效利用(检查执行计划)
- [ ] 没有N+1查询模式(消除了相关子查询)
SQL质量:
- [ ] SELECT中只包含必要的列(不使用SELECT *)
- [ ] 在多表查询中使用显式表别名
- [ ] 正确的NULL处理(COALESCE, IS NULL 与 = NULL)
- [ ] 比较中的数据类型匹配(无隐式转换)
- [ ] 使用参数化查询(防止SQL注入)
优化:
- [ ] 在适用情况下使用窗口函数代替自连接
- [ ] 使用EXISTS代替NOT IN以获得更好的NULL处理
- [ ] 为频繁查询建议覆盖索引
- [ ] 重写查询以消除相关子查询
文档:
- [ ] 注释中解释了复杂查询逻辑
- [ ] CTE名称具有描述性且自文档化
- [ ] 记录了预期的输出格式
- [ ] 记录了性能特征
附加资源
- 详细技术参考:参见 REFERENCE.md
- 代码示例与模式:参见 EXAMPLES.md