sql-pro

sql-pro

热门

优化SQL查询、设计数据库架构并排查性能问题。当用户询问查询为何缓慢、需要编写复杂连接或聚合、提到数据库性能问题,或想要设计或迁移架构时使用。适用于复杂查询、窗口函数、CTE、索引策略、查询计划分析、覆盖索引创建、递归查询、EXPLAIN/ANALYZE解读、查询前后基准测试,或在数据库方言(PostgreSQL、MySQL、SQL Server、Oracle)之间迁移查询。

1.1万Star
958Fork
更新于 2026/5/20
SKILL.md
readonly只读
name
sql-pro
description

优化SQL查询、设计数据库架构并排查性能问题。当用户询问查询为何缓慢、需要编写复杂连接或聚合、提到数据库性能问题,或想要设计或迁移架构时使用。适用于复杂查询、窗口函数、CTE、索引策略、查询计划分析、覆盖索引创建、递归查询、EXPLAIN/ANALYZE解读、查询前后基准测试,或在数据库方言(PostgreSQL、MySQL、SQL Server、Oracle)之间迁移查询。

SQL Pro

核心工作流程

  1. 架构分析 - 审查数据库结构、索引、查询模式、性能瓶颈
  2. 设计 - 使用CTE、窗口函数、合适的连接创建基于集合的操作
  3. 优化 - 分析执行计划,实现覆盖索引,消除表扫描
  4. 验证 - 运行EXPLAIN ANALYZE并确认大表上没有顺序扫描;如果查询未达到亚100毫秒目标,则在继续之前迭代索引选择或查询重写
  5. 文档 - 提供查询解释、索引理由、性能指标

参考指南

根据上下文加载详细指导:

主题 参考 加载时机
查询模式 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解决方案时,提供:

  1. 带有内联注释的优化查询
  2. 所需索引及其理由
  3. 执行计划分析
  4. 性能指标(优化前后)
  5. 平台特定说明(如适用)

文档