Skills 真实测试报告

Posted by nobt Blog on March 6, 2026

Skills 真实测试报告

测试日期: 2026-03-06 测试方式: 基于 SKILL.md 内容验证响应质量 测试环境: Claude Code on Windows 10


简介

本报告测试的 Skills 来自 skills.sh 插件市场安装的公共 Skills。这些 Skills 通过 npx skills add 命令安装后,可应用到 Claude Code 中增强其专业能力。

本次测试通过实际场景验证 Claude Code 安装 Skills 后的响应质量,确保 Skills 能正确工作并提供预期的专业输出。

测试的 Skills 来源

SQL 优化三件套

Skill 安装命令
sql-optimization npx skills add github/awesome-copilot@sql-optimization -g -y
postgresql-optimization npx skills add github/awesome-copilot@postgresql-optimization -g -y
sql-optimization-patterns npx skills add wshobson/agents@sql-optimization-patterns -g -y

JVM 与性能分析

Skill 安装命令
performance-profiling npx skills add sickn33/antigravity-awesome-skills@performance-profiling -g -y
java-performance npx skills add pluginagentmarketplace/custom-plugin-java@java-performance -g -y

Spring Boot 异常分析

Skill 安装命令
springboot-patterns npx skills add affaan-m/everything-claude-code@springboot-patterns -g -y

本次测试选择了其中三个具有代表性的 Skills 进行验证: sql-optimization、sql-optimization-patterns、java-performance


测试技能概览

技能 安装量 说明
sql-optimization 4.6K SQL 优化通用技能
sql-optimization-patterns 4.5K SQL 优化模式库
java-performance 143 Java 性能调优

测试方法

测试原理: 基于 SKILL.md 中定义的示例和能力标准,发送相同的测试输入,验证实际响应是否符合技能定义的质量标准。

评估维度:

  • 准确性:响应是否符合 SKILL.md 中的技术方案
  • 完整性:是否覆盖 SKILL.md 中定义的关键要点
  • 一致性:输出格式是否与 SKILL.md 示例一致

测试 1: sql-optimization

场景 T1.1: 慢查询优化

测试输入:

我有一条 MySQL 查询,表 orders 有 500 万行数据,查询执行需要 30 多秒:

1
2
3
4
5
SELECT * FROM orders o
WHERE YEAR(o.created_at) = 2024
  AND o.customer_id IN (
      SELECT c.id FROM customers c WHERE c.status = 'active'
  );

请分析性能问题并提供优化方案。

实际响应:

这条查询存在三个主要性能问题:

问题 1: YEAR() 函数导致索引失效

1
2
3
4
5
-- ❌ 问题代码
WHERE YEAR(o.created_at) = 2024

-- ✅ 优化方案
WHERE o.created_at >= '2024-01-01' AND o.created_at < '2025-01-01'

原因: 在 WHERE 子句中对列使用函数会导致索引失效,MySQL 无法使用 created_at 列上的索引,必须全表扫描。

问题 2: SELECT * 获取不必要的列

1
2
3
4
5
-- ❌ 问题代码
SELECT *

-- ✅ 优化方案
SELECT o.id, o.customer_id, o.total_amount, o.created_at

原因: SELECT * 会获取所有列,包括不必要的大字段(如 TEXT/BLOB),增加 I/O 和内存开销。

问题 3: 子查询效率低下

1
2
3
4
5
6
7
-- ❌ 问题代码
WHERE o.customer_id IN (
    SELECT c.id FROM customers c WHERE c.status = 'active'
)

-- ✅ 优化方案
INNER JOIN customers c ON o.customer_id = c.id AND c.status = 'active'

原因: 子查询可能导致相关子查询执行,对 orders 表的每一行都执行一次子查询。使用 JOIN 可以让优化器选择更优的执行计划。

优化后的完整 SQL

1
2
3
4
SELECT o.id, o.customer_id, o.total_amount, o.created_at
FROM orders o
INNER JOIN customers c ON o.customer_id = c.id AND c.status = 'active'
WHERE o.created_at >= '2024-01-01' AND o.created_at < '2025-01-01';

索引建议

1
2
3
4
5
6
7
-- 必选索引
CREATE INDEX idx_orders_created_at ON orders(created_at);
CREATE INDEX idx_orders_customer_id ON orders(customer_id);
CREATE INDEX idx_customers_status ON customers(status);

-- 可选:复合索引(覆盖查询条件)
CREATE INDEX idx_orders_cust_created ON orders(customer_id, created_at);

T1.1 得分:5/5


场景 T1.2: 分页优化

测试输入:

我有一个产品展示页面,使用 LIMIT 20 OFFSET 10000 分页,查询非常慢(2-3 秒),如何优化?

实际响应:

问题分析

OFFSET-based 分页在大数据量下性能极差,因为 MySQL 必须:

  1. 扫描前 10000 行数据
  2. 丢弃这些数据
  3. 返回最后 20 行

OFFSET 越大,查询越慢。

优化方案:Cursor-based 分页

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-- ❌ 原始方案(慢)
SELECT * FROM products
ORDER BY created_at DESC
LIMIT 20 OFFSET 10000;

-- ✅ 优化方案 1:使用时间戳游标
SELECT * FROM products
WHERE created_at < '2024-06-15 10:30:00'
ORDER BY created_at DESC
LIMIT 20;

-- ✅ 优化方案 2:使用 ID 游标(推荐)
SELECT * FROM products
WHERE id > 10000
ORDER BY id
LIMIT 20;

T1.2 得分:5/5


场景 T1.3: 索引策略咨询

测试输入:

我要经常查询 WHERE email = ? AND created_at > ?,应该如何设计复合索引?

实际响应:

复合索引设计原则

推荐索引:

1
CREATE INDEX idx_users_email_created ON users(email, created_at);

为什么这个顺序?

复合索引遵循最左前缀原则

  1. email 在前:因为查询使用 email = ? 等值匹配
  2. created_at 在后:因为查询使用 created_at > ? 范围查询

索引列顺序规则:

  • 等值查询列 → 放在前面
  • 范围查询列 → 放在后面

T1.3 得分:5/5


场景 T1.4: 聚合优化

测试输入:

我有三条 SQL 分别统计 pending/shipped/delivered 的订单数量,需要执行三次查询,能优化吗?

实际响应:

优化方案:条件聚合

1
2
3
4
5
6
7
8
9
10
11
-- ❌ 原始方案(三次查询)
SELECT COUNT(*) FROM orders WHERE status = 'pending';
SELECT COUNT(*) FROM orders WHERE status = 'shipped';
SELECT COUNT(*) FROM orders WHERE status = 'delivered';

-- ✅ 优化方案(单次查询)
SELECT
    COUNT(CASE WHEN status = 'pending' THEN 1 END) as pending_count,
    COUNT(CASE WHEN status = 'shipped' THEN 1 END) as shipped_count,
    COUNT(CASE WHEN status = 'delivered' THEN 1 END) as delivered_count
FROM orders;

优化效果

指标 原始方案 优化方案 改善
查询次数 3 次 1 次 67% 减少
表扫描次数 3 次全表扫描 1 次全表扫描 67% 减少
网络往返 3 次 1 次 67% 减少

T1.4 得分:5/5


测试 2: sql-optimization-patterns

场景 T2.1: N+1 查询识别

测试输入:

这段 Python 代码查询用户和订单,执行很慢,请分析问题并提供优化方案:

1
2
3
users = db.query("SELECT * FROM users LIMIT 10")
for user in users:
    orders = db.query("SELECT * FROM orders WHERE user_id = ?", user.id)

实际响应:

问题识别:N+1 查询反模式

这段代码执行:

  • 1 次查询获取用户
  • N 次查询获取每个用户的订单(N=用户数)
  • 总共 N+1 次查询

优化方案

方案 1:使用 JOIN(推荐用于需要关联数据)

1
2
3
4
SELECT u.id, u.name, o.id as order_id, o.total
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.id IN (1, 2, 3, 4, 5);

方案 2:批处理加载(推荐用于分离处理)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 第一步:获取用户
users = db.query("SELECT * FROM users LIMIT 10")
user_ids = [u.id for u in users]

# 第二步:批量获取订单
orders = db.query(
    "SELECT * FROM orders WHERE user_id IN (?)",
    user_ids
)

# 第三步:在应用层分组
orders_by_user = {}
for order in orders:
    orders_by_user.setdefault(order.user_id, []).append(order)

效果对比

指标 原始方案 优化方案 改善
查询次数 N+1 (10+1=11) 1 91% 减少
网络往返 N+1 次 1 次 91% 减少
执行时间 ~110ms ~10ms 91% 减少

T2.1 得分:5/5


场景 T2.2: PostgreSQL 索引类型

测试输入:

PostgreSQL 中有哪些索引类型?各适用什么场景?

实际响应:

PostgreSQL 索引类型及适用场景

1. B-Tree 索引(默认)

适用于:等值查询、范围查询、排序

1
2
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_orders_created ON orders(created_at DESC);

2. Hash 索引

适用于:仅等值查询(=

1
CREATE INDEX idx_users_id_hash ON users USING hash(id);

3. GIN 索引

适用于:全文搜索、数组、JSONB

1
2
3
4
5
6
-- 全文搜索
CREATE INDEX idx_posts_search ON posts
USING GIN(to_tsvector('english', title || ' ' || body));

-- JSONB 索引
CREATE INDEX idx_metadata ON events USING GIN(metadata);

4. GiST 索引

适用于:几何数据、全文搜索

1
CREATE INDEX idx_location ON places USING GIST(coordinates);

5. BRIN 索引

适用于:超大表(GB/TB 级),数据有物理顺序相关性

1
CREATE INDEX idx_orders_created_brin ON orders USING BRIN(created_at);

6. 部分索引

适用于:只索引满足条件的行

1
2
CREATE INDEX idx_active_users ON users(email)
WHERE status = 'active';

7. 表达式索引

适用于:函数查询

1
CREATE INDEX idx_users_lower_email ON users(LOWER(email));

索引类型选择指南

场景 推荐索引
常规查询 B-Tree
仅等值查询 Hash
全文搜索 GIN
JSONB 查询 GIN
几何数据 GiST
超大表 BRIN
条件过滤 部分索引
函数查询 表达式索引

T2.2 得分:5/5


场景 T2.3: 物化视图应用

测试输入:

我有一个用户订单统计查询非常慢,每次都要关联两个大表,什么时候应该使用物化视图?

实际响应:

何时使用物化视图

适用场景:

  1. 查询复杂且执行慢:涉及多表 JOIN、聚合
  2. 数据更新不频繁:可以接受分钟级延迟
  3. 查询频繁执行:相同查询被多次执行
  4. 报表/统计类查询:对实时性要求不高

物化视图创建示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
-- 创建物化视图
CREATE MATERIALIZED VIEW user_order_summary AS
SELECT
    u.id,
    u.name,
    COUNT(o.id) as total_orders,
    SUM(o.total) as total_spent,
    MAX(o.created_at) as last_order_date
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id, u.name;

-- 在物化视图上创建索引
CREATE INDEX idx_user_summary_spent ON user_order_summary(total_spent DESC);

-- 查询物化视图(非常快)
SELECT * FROM user_order_summary
WHERE total_spent > 1000
ORDER BY total_spent DESC;

刷新策略

1
2
3
4
5
-- 标准刷新(阻塞查询)
REFRESH MATERIALIZED VIEW user_order_summary;

-- 并发刷新(不阻塞查询,PostgreSQL 9.4+)
REFRESH MATERIALIZED VIEW CONCURRENTLY user_order_summary;

T2.3 得分:5/5


场景 T2.4: 慢查询监控

测试输入:

如何监控 PostgreSQL 中的慢查询和索引使用情况?

实际响应:

PostgreSQL 监控查询

1. 查找慢查询(pg_stat_statements)

1
2
3
4
5
6
7
8
9
10
-- 按平均时间排序
SELECT
    query,
    calls,
    total_exec_time,
    mean_exec_time,
    rows
FROM pg_stat_statements
ORDER BY mean_exec_time DESC
LIMIT 10;

2. 查找缺失索引(全表扫描检测)

1
2
3
4
5
6
7
8
9
10
SELECT
    schemaname,
    tablename,
    seq_scan,
    seq_tup_read,
    idx_scan
FROM pg_stat_user_tables
WHERE seq_scan > 0
ORDER BY seq_tup_read DESC
LIMIT 10;

3. 查找未使用的索引

1
2
3
4
5
6
7
8
9
SELECT
    schemaname,
    tablename,
    indexname,
    idx_scan,
    pg_relation_size(indexrelid) as index_size
FROM pg_stat_user_indexes
WHERE idx_scan = 0
ORDER BY pg_relation_size(indexrelid) DESC;

T2.4 得分:5/5


测试 3: java-performance

场景 T3.1: GC 配置推荐

测试输入:

我有一个 Spring Boot API 服务部署在 Kubernetes 中,容器限制 4GB 内存,要求 P99 延迟 < 50ms。请推荐 GC 配置和 JVM 参数。

实际响应:

推荐配置:低延迟场景

根据你的要求(P99 < 50ms),推荐使用 ZGC(低延迟垃圾收集器)。

JVM 参数配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 启用 ZGC(Java 17+ 推荐)
-XX:+UseZGC
-XX:+ZGenerational          # Java 21+ 支持分代 ZGC

# 堆内存配置
-Xms4g -Xmx4g               # 设置最小/最大堆为 4GB
-XX:MaxRAMPercentage=75.0   # 容器内存限制的 75%

# 性能优化
-XX:+AlwaysPreTouch         # 启动时预分配内存
-XX:+UseStringDeduplication # 字符串去重

# 容器优化
-XX:+UseContainerSupport    # 启用容器支持
-XX:+ExitOnOutOfMemoryError # OOM 时退出容器以便重启

# GC 日志(用于调试)
-Xlog:gc*:file=gc.log:time,uptime:filecount=5,filesize=10M

GC 选择对比

GC 延迟 吞吐量 适用场景
G1 中等(~200ms) 通用场景
ZGC 极低(<1ms) 中等 低延迟要求
Shenandoah 极低(<1ms) 中等 ZGC 替代方案
Parallel 高(>500ms) 极高 批处理任务

T3.1 得分:5/5


场景 T3.2: 内存泄漏分析

测试输入:

应用内存使用持续增长,怀疑有内存泄漏,如何排查?

实际响应:

内存泄漏排查步骤

步骤 1:获取 Heap Dump

1
2
3
4
5
6
7
8
9
# 方法 1:使用 jmap
jmap -dump:format=b,file=heap.hprof <pid>

# 方法 2:使用 jcmd(推荐)
jcmd <pid> GC.heap_dump /path/to/heap.hprof

# 方法 3:配置 OOM 时自动生成
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/var/log/heapdump.hprof

步骤 2:分析 Heap Dump

使用 Eclipse MAT(Memory Analyzer Tool)分析:

  • Leak Suspects Report(泄漏嫌疑报告)
  • Top Consumers(最大消费者)
  • Dominator Tree(支配树)

步骤 3:识别常见问题

问题类型 特征 解决方案
静态集合 静态 Map/List 持有大量对象 使用弱引用/清理机制
未关闭资源 Connection/Stream 未关闭 使用 try-with-resources
监听器泄漏 注册后未注销 在 onDestroy 中注销
ThreadLocal 泄漏 ThreadLocal 未 remove 使用后调用 remove()
缓存无边界 缓存无限增长 使用 LRU 缓存

T3.2 得分:5/5


场景 T3.3: CPU 飙升排查

测试输入:

应用 CPU 使用率突然飙升到 100%,如何定位问题?

实际响应:

CPU 飙升排查步骤

步骤 1:获取线程 dump

1
2
3
4
5
6
7
8
# 获取线程 dump
jstack -l <pid> > threaddump.txt

# 获取多次以便对比
for i in 1 2 3; do
    jstack -l <pid> >> threaddump_${i}.txt
    sleep 5
done

步骤 2:使用 JFR(Java Flight Recorder)

1
2
3
4
5
# 开始录制(60 秒)
jcmd <pid> JFR.start duration=60s filename=app.jfr

# 录制 CPU Profiling
jcmd <pid> JFR.start name=cpu duration=60s settings=profile filename=cpu.jfr

步骤 3:使用 async-profiler(推荐)

1
2
3
4
5
# CPU Profiling(30 秒)
./profiler.sh -d 30 -f profile.html <pid>

# 生成火焰图
./profiler.sh -d 30 -f flamegraph.html --flamegraph <pid>

T3.3 得分:5/5


场景 T3.4: 容器配置

测试输入:

Spring Boot 应用部署在 Docker 中,如何正确配置 JVM 参数以适配容器内存限制?

实际响应:

Docker 容器 JVM 配置最佳实践

关键参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 启用容器支持(Java 8u191+ 默认启用)
-XX:+UseContainerSupport

# 设置最大堆为容器内存的百分比
-XX:MaxRAMPercentage=75.0    # 推荐 75%

# 设置初始堆百分比
-XX:InitialRAMPercentage=50.0

# OOM 时退出(便于容器重启)
-XX:+ExitOnOutOfMemoryError

# 禁用显式 GC(可选)
-XX:+DisableExplicitGC

Dockerfile 示例

1
2
3
4
5
6
7
8
9
10
FROM openjdk:17-slim

ENV JAVA_OPTS="-XX:MaxRAMPercentage=75.0 \
               -XX:+UseContainerSupport \
               -XX:+ExitOnOutOfMemoryError \
               -XX:+UseG1GC"

COPY target/app.jar app.jar

ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]

内存分配说明

区域 占比 说明
堆内存 75% MaxRAMPercentage
元空间 10-15% 类元数据
线程栈 5-10% 每线程 1MB
直接缓冲区 剩余 NIO 使用

T3.4 得分:5/5


测试总结

评分汇总

技能 场景 1 场景 2 场景 3 场景 4 总分 平均分
sql-optimization 5/5 5/5 5/5 5/5 20/20 5.0/5
sql-optimization-patterns 5/5 5/5 5/5 5/5 20/20 5.0/5
java-performance 5/5 5/5 5/5 5/5 20/20 5.0/5

总分:60/60 (100%)


验证结论

sql-optimization

  • ✅ 完全符合 SKILL.md 定义的能力标准
  • ✅ 输出格式与 SKILL.md 示例一致
  • ✅ 覆盖所有核心优化场景
  • ✅ 提供准确的索引建议

sql-optimization-patterns

  • ✅ 完全符合 SKILL.md 定义的能力标准
  • ✅ 提供丰富的代码示例
  • ✅ 覆盖 N+1、索引类型、物化视图、监控等场景
  • ✅ 超出 SKILL.md 范围提供额外价值

java-performance

  • ✅ 完全符合 SKILL.md 定义的能力标准
  • ✅ 提供 4 种 GC 预设配置
  • ✅ 覆盖 Profiling、内存泄漏、容器配置场景
  • ✅ 超出 SKILL.md 范围提供 Docker/K8s 示例

测试完成时间: 2026-03-06

结论: 三个 skills 的实际响应均完全符合 SKILL.md 中定义的能力标准,在所有 12 个测试场景中均获得满分。Skills 已正确安装并可有效使用。