Ziptax Tool Free
支持按地址、邮编或经纬度查询美国销售税率,含CLI封装与API调用说明。
下载 57
编写、审查并优化 SQL 查询;设计数据模型、索引与约束;规划任意关系型数据库的迁移。适用于查询缓慢、EXPLAIN 显示全表扫描、索引未被使用,或 JOIN 后出现重复、缺失、总计异常等情况。
openclaw skills install @ivangdavila/sql命令、参数、文件名以原文为准
用户偏好和记忆数据存储在 ~/Clawic/data/sql/ 目录下(首次使用请参考 setup.md,文件格式详见 memory-template.md)。若旧数据位于 ~/sql/ 或 ~/clawic/sql/,请将其移至 ~/Clawic/data/sql/。
pg 处理;也不适用于框架内 ORM 层的模型设计——该场景由 prisma 处理| 场景 | 推荐操作 |
|---|---|
| 查询变慢但原因不明 | 执行 EXPLAIN (ANALYZE, BUFFERS),优先修复代价最高的节点(→ 参见《阅读 EXPLAIN》与 performance.md) |
| 昨天还快的查询今天变慢 | 检查统计信息、数据增长或执行计划变更 —— 参考 debug.md 中的回归链分析 |
| 索引存在但未被使用 | 可能原因:列上使用了函数、类型不匹配、列顺序错误或选择性过低(→ 参见《陷阱》与 performance.md) |
| JOIN 后汇总值异常膨胀 | 1:N 扇出问题 —— 应先聚合再 JOIN(→ 参见《陷阱》) |
| JOIN 后部分数据丢失 | LEFT JOIN 在 WHERE 子句中被过滤,导致退化为内连接(→ 参见《陷阱》) |
| 分页超过前几千条记录 | 使用基于键集的分页,避免使用 OFFSET(→ 参见 patterns.md) |
| 出现死锁、锁超时或“无法获取锁” | 参考 transactions.md:关注锁顺序与隔离级别 |
| “连接过多”或应用连接时卡住 | 在 max_connections 之前调整连接池大小(→ 参见 operations.md 与 orm.md) |
| 读-修改-写竞争或任务队列问题 | 使用 SELECT ... FOR UPDATE,队列场景可添加 SKIP LOCKED(→ 参见 patterns.md) |
| 对线上表执行结构变更 | 采用 expand → migrate → contract 流程,优先设置 lock_timeout(→ 参见 operations.md) |
| 从零开始设计数据模型 | 主键选择、基数分析、范式化原则,何时反范式化(→ 参见 modeling.md) |
| 已知结构需求(租户、标签、审计日志、状态、历史记录等) | 参考 schemas.md |
| 存储或查询 JSON / 半结构化数据 | 参考 json.md |
| 用户行为分析:漏斗、留存、滚动汇总、物化视图 | 参考 analytics.md |
| 导入 CSV、数据转储或跨引擎迁移 | 参考 data-loading.md |
| 时间戳偏差数小时、夏令时、周/财年边界问题 | 参考 datetime.md |
| 语句在一个引擎可用,另一个不可用 | 参考 dialects.md |
| 权限管理、最小权限原则、行级安全、PII 数据擦除、加密 | 参考 security.md |
| 固定测试数据、测试环境隔离、迁移流程验证 | 参考 testing.md |
| ORM 生成低效 SQL、N+1 查询、神秘事务 | 参考 orm.md |
| 单节点达到性能极限:考虑副本、分片、缓存 | 参考 scaling.md |
| 选择数据库引擎 | SQLite(嵌入式/本地)· PostgreSQL(服务器默认)· MySQL(平台强制要求)· SQL Server(.NET/Windows 环境)(→ 参见 dialects.md) |
| 其他情况 | 将问题缩小到最小可复现表,然后:
modeling.md / schemas.mdpatterns.mdperformance.mdoperations.md |?、$1)防止值注入攻击,但表名/列名无法绑定——动态名称必须通过硬编码白名单校验,禁止拼接用户输入。完整攻击面涵盖 LIKE 和 ORDER BY 注入(→ 参见 security.md)。INT 类型在 2,147,483,647 时溢出——以每秒 100 次插入计算,约 248 天后发生,修复需停机。随机 UUIDv4 会破坏 B 树插入局部性;推荐使用 UUIDv7/ULID 保持插入局部性(→ 参见 modeling.md)。(user_id, created_at) 可支持 WHERE user_id = ? AND created_at > ? 以及仅 WHERE user_id = ? 的查询,但不能支持 WHERE created_at = ? 单独使用。当筛选条件命中超过 5%-10% 行时,全表扫描是优化器合理判断,非故障。DELETE(尤其带 ON DELETE CASCADE 时)都需扫描整张子表——这是多数系统中最慢的删除操作。BEGIN...COMMIT 中发起 HTTP 请求或等待用户输入:长时间打开的事务会持有锁,在 PostgreSQL 中还会阻塞 vacuum,导致表膨胀。超过 1 分钟的事务(监控阈值)将被调查。NOT IN (子查询) 在子查询返回任意一个 NULL 时返回空集——应改用 NOT EXISTS。x = NULL 永远不为真——应使用 IS NULL。COUNT(col) 忽略 NULL 值;COUNT(*) 统计行数。聚合在无数据时返回 NULL 而非 0——如图表或不变量需要数值,应使用 COALESCE 包裹。NUMERIC/DECIMAL(浮点数会丢失精度);时间戳使用 TIMESTAMPTZ 存储为 UTC(→ 参见 datetime.md);字符串使用 TEXT(PostgreSQL 与 SQLite),避免 varchar(255) 这类无意义的限制;MySQL 字符集使用 utf8mb4(MySQL 的 utf8 仅支持 3 字节,无法存储表情符号)。operations.md)。单次部署的列重命名会中断所有仍在运行旧代码的实例。pg_stat_statements 按 total_exec_time 排序(或使用 pt-query-digest 解析 MySQL 慢查询日志),找出总成本最高的查询——通常不是用户抱怨的那个。总成本 = 平均延迟 × 调用次数:一个每分钟调用 10,000 次的 5ms 查询(每分钟 50 秒)远超每小时一次的 2 秒报表。未排序就优化等于盲目猜测。EXPLAIN (ANALYZE, BUFFERS) SELECT * FROM orders WHERE user_id = 5; -- PostgreSQL
EXPLAIN ANALYZE SELECT ...; -- MySQL >=8.0.18
EXPLAIN QUERY PLAN SELECT * FROM orders WHERE user_id = 5; -- SQLite
SET STATISTICS PROFILE ON; -- SQL Server(或图形化执行计划)重点查看实际执行行为,而非仅看计划。普通 EXPLAIN 仅显示估算值,而估算值正是最容易失真的部分。
Seq Scan / type: ALL 在大表上配合选择性高的过滤条件 → 缺失或无法使用的索引(→ 参见《陷阱》中导致索引失效的原因)Rows Removed by Filter 数值高 → 索引找到了候选行,但过滤条件仍需大量计算;应扩展索引以覆盖过滤条件ANALYZE tablename; 更新;若仍不准,说明优化器假设列间独立,需声明相关性(PostgreSQL ≥10 使用 CREATE STATISTICS,MySQL 8 支持直方图)Buffers: read 大于 hit → 数据来自磁盘;在缓存预热后再次检查,避免误判performance.md-- 复合索引:等值列在前,范围/排序列在后(规则 3)
CREATE INDEX idx_orders_user_status ON orders(user_id, status);
-- 覆盖索引:索引扫描无需回表(PostgreSQL ≥11,SQL Server INCLUDE)
CREATE INDEX idx_orders_user ON orders(user_id) INCLUDE (total);
-- 部分索引:仅索引查询中实际使用的行(PostgreSQL、SQLite、SQL Server)
CREATE INDEX idx_orders_pending ON orders(user_id) WHERE status = 'pending';
-- 表达式索引:使函数可被索引使用(MySQL ≥8.0.13 支持函数索引)
CREATE INDEX idx_users_email_lower ON users(LOWER(email));status)上建立普通索引效果有限;对实际查询的稀有值建立部分索引更有效。(a, b) 上已有索引时,WHERE a = ? 已被覆盖,无需额外创建 (a) 单独索引——会增加写入开销且无收益。添加前检查是否存在冗余前缀。LIKE 'term%' 的支持——需添加 text_pattern_ops 操作类实现前缀搜索。EXPLAIN 显示 Heap Fetches 高,需执行 VACUUM(→ 参见 operations.md)。pg_stat_user_indexes 中 idx_scan = 0),但需在完整业务周期(如月结报告)后执行,避免误删临时使用索引。| 特性 | PostgreSQL | MySQL | SQLite | SQL Server |
|---|---|---|---|---|
| 限制数量 | LIMIT n | LIMIT n | LIMIT n | TOP n / OFFSET-FETCH |
| UPSERT | ON CONFLICT | ON DUPLICATE KEY | ON CONFLICT | MERGE |
| 布尔类型 | true/false | 1/0(TINYINT) | 1/0 | 1/0(BIT) |
| 字符串拼接 | \ | \ | CONCAT() | |
| 自增主键 | GENERATED / SERIAL | AUTO_INCREMENT | INTEGER PRIMARY KEY | IDENTITY |
| DML 返回行 | RETURNING | —(MariaDB 支持) | RETURNING(≥3.35) | OUTPUT |
| 聚合 FILTER | 支持 | 仅 CASE | 支持(≥3.30) | 仅 CASE |
| 事务性 DDL | 支持 | 不支持(隐式提交) | 支持 | 支持 |
| 默认字符串比较 | 区分大小写 | 不区分大小写(_ci 排序规则) | 区分大小写 | 默认不区分大小写 |
日期函数、引号规则、NULL 排序顺序、排序规则等差异详见 dialects.md。
在输出 SQL 前,请确认:
UPDATE/DELETE 是否包含 WHERE 子句?或全表影响是明确意图?SELECT 预览?DISTINCT 掩盖了潜在问题?LIMIT/TOP 是否有确定的 ORDER BY,且包含唯一断言?lock_timeout?变更是否为可扩展模式?dialects.md)用户自定义变量。默认值在用户未指定前生效;配置文件保存于 ~/Clawic/data/sql/config.yaml。
| 变量 | 类型 | 默认值 | 效果 |
|---|---|---|---|
| dialect | postgres \ | mysql \ | mariadb \ |
| engine_version | text(如 15, 8.0.35) | 无 | 控制功能启用门槛(如 RETURNING、函数索引、NULLS NOT DISTINCT);未设置时采用保守语法 |
| identifier_style | snake_case \ | camelCase \ | PascalCase |
| table_naming | plural \ | singular | plural |
| pk_type | bigint-identity \ | uuidv7 \ | uuidv4 \ |
| destructive_guard | bool | true | 开启后,UPDATE/DELETE 无 WHERE、DROP、TRUNCATE 操作将先以事务包裹的形式预览等价 SELECT |
| migration_tool | text(flyway, alembic, golang-migrate, sqitch, ...) | 无 | 生成迁移文件的命名与 up/down 结构(→ 参见 operations.md) |
| timezone_policy | utc \ | local | utc |
| lock_timeout | text(持续时间:500ms, 2s, 10s) | 2s | 每次对线上表执行 DDL 前自动设置 SET lock_timeout(→ 参见 operations.md) |
| batch_size | number(行数,100–100000) | 5000 | 批量 DELETE/UPDATE、回填、批量加载的分块大小(→ 参见 patterns.md、data-loading.md、json.md) |
operations.md 与 testing.md 示例operations.md 与 destructive_guard 机制modeling.md 与 operations.md 顺序orm.md 与 analytics.md 建议schemas.md 与 security.md 选择lock_timeout、batch_size、死锁/序列化失败重试上限、连接池大小规则、告警阈值(连接饱和度、磁盘剩余、事务年龄、备份时效)—— 影响 transactions.md 重试逻辑与 operations.md 告警表operations.md、analytics.md、schemas.md、testing.md 的调度安排| 陷阱 | 为何失败 | 正确做法 |
|---|---|---|
WHERE YEAR(created_at) = 2024 | 无法使用索引,因函数作用于列 | 改为 WHERE created_at >= '2024-01-01' AND created_at < '2025-01-01' |
LIKE '%keyword%' | 无法使用前缀索引 | 若需模糊匹配,考虑全文搜索或倒排索引 |
ORDER BY col 无 LIMIT | 无法保证结果一致性 | 添加 ORDER BY 与 LIMIT,并确保有唯一断言 |
SELECT COUNT(*) FROM large_table | 全表扫描,耗时长 | 用 pg_stat_user_tables 查看近似行数,或使用采样 |
UPDATE table SET col = val WHERE id = ? 无索引 | 严重性能问题 | 确保主键或唯一索引存在 |
INSERT INTO table VALUES (...), (...), ... 大批量 | 可能超出事务限制 | 使用分批插入,结合 batch_size |
JSONB 列上无索引 | 查询慢 | 在常用路径上创建表达式索引(如 CREATE INDEX ON table ((data->>'key'))) |
UNION ALL 无 ORDER BY | 结果顺序不确定 | 显式添加 ORDER BY 以保证一致性 |
ALTER TABLE ADD COLUMN 无 lock_timeout | 可能导致长时间锁表 | 设置 SET lock_timeout,采用 expand-migrate-contract 流程 |
已收录 28 个 Skill