SKILL.md
readonly只读
name
sql-pro
description
优化SQL查询、设计数据库架构并排查性能问题。当用户询问查询为何缓慢、需要编写复杂连接或聚合、提到数据库性能问题,或想要设计或迁移架构时使用。适用于复杂查询、窗口函数、CTE、索引策略、查询计划分析、覆盖索引创建、递归查询、EXPLAIN/ANALYZE解读、查询前后基准测试,或在数据库方言(PostgreSQL、MySQL、SQL Server、Oracle)之间迁移查询。
SQL Pro
核心工作流程
- 架构分析 - 审查数据库结构、索引、查询模式、性能瓶颈
- 设计 - 使用CTE、窗口函数、合适的连接创建基于集合的操作
- 优化 - 分析执行计划,实现覆盖索引,消除表扫描
- 验证 - 运行
EXPLAIN ANALYZE并确认大表上没有顺序扫描;如果查询未达到亚100毫秒目标,则在继续之前迭代索引选择或查询重写 - 文档 - 提供查询解释、索引理由、性能指标
参考指南
根据上下文加载详细指导:
| 主题 | 参考 | 加载时机 |
|---|---|---|
| 查询模式 | references/query-patterns.md |
JOIN、CTE、子查询、递归查询 |
| 窗口函数 | references/window-functions.md |
ROW_NUMBER、RANK、LAG/LEAD、分析函数 |
| 优化 | references/optimization.md |
EXPLAIN计划、索引、统计信息、调优 |
| 数据库设计 | references/database-design.md |
规范化、键、约束、模式 |
| 方言差异 | references/dialect-differences.md |
PostgreSQL vs MySQL vs SQL Server 具体差异 |
快速参考示例
CTE模式
-- 隔离昂贵的子查询逻辑以便重用和可读性
WITH ranked_orders AS (
SELECT
customer_id,
order_id,
total_amount,
ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) AS rn
FROM orders
WHERE status = 'completed' -- 尽早过滤,在连接之前
)
SELECT customer_id, order_id, total_amount
FROM ranked_orders
WHERE rn = 1; -- 每个客户的最新已完成订单
窗口函数模式
-- 分区内的累计总和和排名——无需自连接
SELECT
department_id,
employee_id,
salary,
SUM(salary) OVER (PARTITION BY department_id ORDER BY hire_date) AS running_payroll,
RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS salary_rank
FROM employees;
EXPLAIN ANALYZE解读
-- PostgreSQL:始终使用ANALYZE查看实际行数与估计值
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
SELECT *
FROM orders o
JOIN customers c ON c.id = o.customer_id
WHERE o.created_at > NOW() - INTERVAL '30 days';
输出中需要检查的关键点:
- 大表上的Seq Scan → 添加或修复索引
- actual rows ≫ estimated rows → 运行
ANALYZE <table>刷新统计信息 - Buffers: shared hit vs read → 高
read计数表示缓存/索引缺失
优化前后示例
-- 优化前:相关子查询,每行执行一次(慢)
SELECT order_id,
(SELECT SUM(quantity) FROM order_items oi WHERE oi.order_id = o.id) AS item_count
FROM orders o;
-- 优化后:单次聚合连接(快)
SELECT o.order_id, COALESCE(agg.item_count, 0) AS item_count
FROM orders o
LEFT JOIN (
SELECT order_id, SUM(quantity) AS item_count
FROM order_items
GROUP BY order_id
) agg ON agg.order_id = o.id;
-- 支持性覆盖索引(包含查询涉及的所有列)
CREATE INDEX idx_order_items_order_qty
ON order_items (order_id)
INCLUDE (quantity);
约束
必须做
- 在推荐优化之前分析执行计划
- 使用基于集合的操作而非逐行处理
- 在查询执行中尽早应用过滤(尽可能在连接之前)
- 使用EXISTS而非COUNT进行存在性检查
- 在比较和聚合中显式处理NULL
- 为频繁查询创建覆盖索引
- 使用生产规模的数据量进行测试
禁止做
- 在生产查询中使用SELECT *
- 在基于集合的操作可行时使用游标
- 针对特定方言时忽略平台特定的优化
- 在不考虑数据量和基数的情况下实现解决方案
输出模板
实现SQL解决方案时,提供:
- 带有内联注释的优化查询
- 所需索引及其理由
- 执行计划分析
- 性能指标(优化前后)
- 平台特定说明(如适用)






