如何用 Codex 检查 SQL 查询是否有问题
重点结论:这篇文章的核心不是让 Codex “凭感觉优化 SQL”,而是让它在项目上下文里做结构化审查:先读模型、迁移文件、接口代码和慢查询日志,再输出风险清单、修改建议、验证方式和回滚提醒。 SQL 查询出问题,表面上常见的是页面变慢、接口超时、报表结果不对、数据库 CPU 飙高;更严重的是权限绕过、SQL 注入、误删数据、事务锁等待和线上事故。很多团队只
发布时间 2026/07/04

重点结论:这篇文章的核心不是让 Codex “凭感觉优化 SQL”,而是让它在项目上下文里做结构化审查:先读模型、迁移文件、接口代码和慢查询日志,再输出风险清单、修改建议、验证方式和回滚提醒。 SQL 查询出问题,表面上常见的是页面变慢、接口超时、报表结果不对、数据库 CPU 飙高;更严重的是权限绕过、SQL 注入、误删数据、事务锁等待和线上事故。很多团队只在“接口能跑通”时结束检查,这不够。 用 Codex 检查 SQL 查询是否有问题,正确做法不是只把一段 SQL 粘进去让它评价,而是让 Codex 结合表结构、索引、ORM 写法、接口调用场景、分页方式、权限条件和执行计划一起审查。这样它才能判断这条 SQL 是语法问题、结果口径问题、性能问题,还是安全问题。 OpenAI 官方文档把 Codex 定义为可以读取、编辑和运行代码的 coding agent,并且 Codex cloud 可以在自己的云环境中处理任务。官方最佳实践也强调:复杂任务要给目标、上下文、约束和完成标准,必要时先让 Codex 计划再执行。因此,SQL 审查最适合做成一套固定检查流程,而不是一次性聊天。
为什么 SQL 查询不能只看“能不能跑通”
SQL 查询最容易骗人的地方是:它能返回数据,不代表它是正确的。很多问题只有在数据量变大、并发变高、用户权限更复杂、分页更深、时间区间更长时才暴露。
-
结果可能对不上业务口径:例如漏掉 deleted_at、status、tenant_id、timezone、退款状态或测试数据过滤。
-
性能可能在小数据量下正常,但上线后出现全表扫描、大范围排序、临时表、低效 JOIN 或深分页。
-
安全风险可能藏在字符串拼接、动态排序字段、模糊搜索条件和管理员接口里。
-
事务问题可能在单人测试时不存在,但在并发更新、库存扣减、余额变更、订单状态流转时出错。
-
ORM 写法可能看起来简洁,但实际产生 N+1 查询,导致接口查询次数随列表条数线性增长。
所以,让 Codex 审查 SQL 时,重点不是问“这条 SQL 有没有问题”,而是要求它按数据库、业务、接口和安全四个层面逐项检查。
Codex 适合检查哪些 SQL 问题
| 检查方向 | Codex 可以做什么 | 需要人确认什么 |
|---|---|---|
| 语法与兼容性 | 检查 SQL 语法、函数、方言差异、ORM 查询写法是否可能报错。 | 最终以目标数据库运行结果为准。 |
| 结果正确性 | 比对字段、JOIN、WHERE、GROUP BY、权限条件和业务口径。 | 业务规则是否真实、口径是否最新。 |
| 性能风险 | 识别全表扫描、低效 JOIN、深分页、SELECT *、缺索引、重复查询。 | 真实数据量、索引现状、执行计划和慢查询日志。 |
| 安全风险 | 检查字符串拼接、用户输入、动态 ORDER BY、IN 条件、raw query。 | 敏感接口的权限设计和安全策略。 |
| 事务与并发 | 提示脏写、丢失更新、锁等待、重复扣减、状态流转风险。 | 业务是否需要强一致、幂等或补偿机制。 |
| 可维护性 | 整理 SQL 命名、注释、复用、查询拆分和测试建议。 | 团队代码规范和历史包袱。 |
边界说明:Codex 可以做“第一轮结构化审查”和“修改建议生成”,但不能替代数据库真实压测、DBA 判断、线上监控和安全测试。SQL 最终必须通过执行计划、测试数据和业务验收验证。
开始前要给 Codex 的上下文
只给 SQL 片段,Codex 很容易给出泛泛建议。更好的输入是把 SQL 放回项目环境里,让它知道这条查询服务哪个接口、对应哪些表、数据量大概多少、是否多租户、是否有软删除、是否涉及权限。
-
SQL 本身:原始 SQL、ORM 查询代码、raw query、视图、存储过程或报表脚本。
-
表结构:DDL、迁移文件、Prisma schema、TypeORM entity、Sequelize model、Supabase 表结构。
-
索引信息:已有索引、唯一约束、外键、常用查询字段。
-
调用场景:接口路径、页面入口、定时任务、后台报表、用户搜索、导出任务。
-
数据规模:表的行数级别、单租户数据量、历史数据保留周期。
-
问题现象:接口慢、结果不准、CPU 高、锁等待、数据库连接池耗尽、慢查询日志。
-
数据库类型:PostgreSQL、MySQL、SQLite、SQL Server、Supabase、Neon、PlanetScale 等。
如果你用的是 Codex cloud,可以让它直接读取仓库里的 schema、migration、API route、service、repository、tests 和 seed 数据。这样审查质量通常比手工复制一段 SQL 高。
基础流程:让 Codex 做一次 SQL 查询审查
-
先让 Codex 定位查询来源:这条 SQL 从哪个页面、接口、函数、任务或报表触发。
-
让 Codex 读取表结构、字段含义、索引、约束和 ORM model。
-
让 Codex 列出查询意图:这条 SQL 试图回答什么业务问题,应该返回哪些数据。
-
让 Codex 按“正确性、性能、安全、事务、可维护性”输出问题清单。
-
让 Codex 给出修改方案,但要求每条建议必须说明原因、影响范围和验证方法。
-
让 Codex 生成测试用例或本地验证步骤,例如边界数据、空数据、跨租户数据、软删除数据、重复数据。
-
如果涉及性能,让 Codex 根据 EXPLAIN / EXPLAIN ANALYZE 输出解释风险,而不是只凭经验猜。
-
最后让 Codex 输出“可直接发 PR 的改动总结”和“需要人工确认的风险点”。
可直接复制的 Codex 指令:基础版
请帮我审查这个项目里的 SQL 查询是否有问题。 目标:找出查询在结果正确性、性能、安全和可维护性上的风险。 上下文: - 数据库类型:PostgreSQL / MySQL / SQLite / Supabase / 其他 - 查询所在文件:@填写具体文件路径 - 相关表结构:请读取 migrations / schema / models - 调用入口:请读取对应 API route / service / repository - 业务意图:这条查询用于【填写页面或接口目的】 请按以下结构输出: 1. 这条查询实际在做什么 2. 可能的结果正确性问题 3. 可能的性能问题 4. 是否存在 SQL 注入或用户输入拼接风险 5. 是否存在权限、tenant_id、软删除、状态过滤遗漏 6. 是否存在 N+1、重复查询、深分页或 SELECT * 问题 7. 推荐修改方案,按高 / 中 / 低优先级排序 8. 每条修改建议的验证方式 要求: - 不要直接大改代码,先输出审查报告 - 不确定的地方标记“需要人工确认” - 涉及索引建议时,说明适用条件和可能副作用 - 涉及安全风险时,优先给出参数化查询或 ORM 安全写法
可直接复制的 Codex 指令:慢查询专项版
请针对下面的慢查询做性能审查。 我会提供: - SQL 原文或 ORM 查询代码 - EXPLAIN / EXPLAIN ANALYZE 输出 - 相关表的行数级别 - 已有索引 - 慢查询日志中的耗时 请你完成: 1. 解释执行计划中的关键节点,包括扫描方式、JOIN 方式、排序、聚合、过滤和估算行数。 2. 判断是否存在全表扫描、索引未命中、低选择性索引、排序溢出、临时表或深分页风险。 3. 判断 SQL 写法是否导致索引失效,例如函数包裹字段、前置通配符 LIKE、隐式类型转换、OR 条件过宽。 4. 给出可选优化方案:改 SQL、加索引、拆查询、预聚合、分页改游标、缓存、物化视图。 5. 每个方案说明收益、风险、验证方式和回滚方式。 输出格式: - 问题摘要 - 证据 - 建议改法 - 验证命令 - 风险和副作用
可直接复制的 Codex 指令:SQL 注入专项版
请帮我审查项目里是否存在 SQL 注入风险,重点检查 raw SQL、字符串拼接、动态 WHERE、动态 ORDER BY、动态 IN 条件和搜索接口。 检查范围: - @app/api - @src/server - @src/lib/db - @prisma/schema.prisma 或 migrations 请输出: 1. 找到的风险文件和代码位置 2. 用户输入从哪里进入查询 3. 查询是否使用参数化、ORM 查询构造器或安全绑定 4. 是否存在字符串拼接、模板字符串拼接、未校验排序字段、未限制字段名、未限制表名等风险 5. 推荐修复方案 6. 修复后的测试用例 约束: - 不要把用户输入直接拼进 SQL - 动态字段名必须使用 allowlist - 排序方向只能允许 asc / desc - 搜索关键词必须参数化 - 输出不要包含真实密钥或生产数据
重点检查维度 1:结果正确性
结果正确性是第一优先级。SQL 优化得再快,如果统计口径错了,反而会更危险。Codex 审查时要让它先复述业务意图,再反推查询条件是否完整。
-
是否漏掉 tenant_id、user_id、organization_id、workspace_id 等隔离条件。
-
是否漏掉 deleted_at、archived、disabled、status、is_test、is_internal 等过滤条件。
-
时间区间是否包含时区问题,是否使用 created_at 还是 paid_at、finished_at、updated_at。
-
JOIN 是否造成重复行,是否需要 DISTINCT 或先聚合再 JOIN。
-
LEFT JOIN 被 WHERE 条件误写成 INNER JOIN 效果。
-
COUNT、SUM、AVG 是否受重复 JOIN、NULL 值、退款、取消订单、测试数据影响。
-
分页排序字段是否稳定,是否需要二级排序字段保证结果不跳动。
重点检查维度 2:性能和索引
SQL 性能不能只靠经验判断。PostgreSQL 和 MySQL 都提供 EXPLAIN 相关能力,用来查看数据库优化器如何处理查询。PostgreSQL 文档说明 EXPLAIN 可以看到查询计划、扫描方式和成本估算;MySQL 文档也说明 EXPLAIN 会展示优化器对语句执行方式的判断。
| 风险点 | Codex 应该检查什么 | 常见改法 |
|---|---|---|
| 全表扫描 | WHERE 条件是否命中索引,表数据量是否已经不可接受。 | 补索引、改条件、拆查询、增加归档策略。 |
| 低效 JOIN | JOIN 字段是否有索引,JOIN 顺序是否异常,是否先过滤再连接。 | 补外键相关索引、缩小中间结果、改写 JOIN。 |
| 深分页 | OFFSET 很大时是否越来越慢。 | 改游标分页或基于时间 / ID 翻页。 |
| 大范围排序 | ORDER BY 是否无法走索引,是否产生临时排序。 | 组合索引、限制范围、异步导出。 |
| SELECT * | 是否取了页面根本不用的字段。 | 只选择必要字段,尤其避免大文本和 JSON。 |
| 函数包裹字段 | WHERE DATE(created_at) 这类写法是否影响索引使用。 | 改成范围查询。 |
| 前置通配符 | LIKE "%keyword%" 是否无法利用普通 B-tree 索引。 | 全文索引、搜索服务、合理降级。 |
索引不是越多越好。PostgreSQL 官方文档也提醒,索引能帮助更快找到行,但会给数据库带来额外开销。因此 Codex 给出“加索引”建议时,必须说明适用查询、字段顺序、写入成本和回滚方式。
重点检查维度 3:SQL 注入风险
SQL 注入的高风险区域通常不在简单 ORM 查询里,而在 raw SQL、动态排序、动态筛选、报表查询、后台搜索、批量导出和拼接式条件生成。OWASP 的 SQL Injection Prevention Cheat Sheet 明确强调,动态查询拼接用户输入是注入问题的重要来源,防护方式应优先使用参数化查询、存储过程、allowlist 输入验证等方式。
-
检查是否使用字符串拼接生成 WHERE 条件。
-
检查是否把用户输入直接拼进 LIKE、IN、ORDER BY、LIMIT、OFFSET。
-
检查动态表名、字段名、排序字段是否有 allowlist。
-
检查搜索接口是否对关键词做参数绑定,而不是模板字符串拼接。
-
检查是否把管理员筛选条件复用到普通用户接口,导致越权查询。
-
检查日志里是否输出完整 SQL 和敏感参数。
重点检查维度 4:N+1 查询
N+1 查询是列表页、Dashboard、GraphQL Resolver、后台表格里很常见的问题。典型表现是先查一批列表,再对每一行单独查关联数据。数据少时看不出来,数据一多接口就变慢。Prisma 官方文档也把 N+1 描述为循环查询结果后,对每条结果继续执行额外查询的问题。
让 Codex 检查 N+1 时,不要只查 SQL 文件,也要查 controller、service、repository、resolver、component loader 和 ORM 查询链。很多 N+1 不是 SQL 原文造成的,而是代码循环造成的。
请检查这个列表接口是否存在 N+1 查询。 范围:@填写接口文件、service、repository、resolver 请你: 1. 画出接口的数据读取流程 2. 标出循环里是否有数据库查询 3. 估算列表返回 20 / 100 / 1000 条数据时会发起多少次查询 4. 判断是否能用 JOIN、include、batch loading、预聚合或缓存解决 5. 给出修改建议和测试方式
重点检查维度 5:事务、并发和数据一致性
不是所有 SQL 问题都体现在 SELECT 上。订单、库存、余额、优惠券、会员权益、任务领取、状态流转,都可能因为事务和并发控制不足出现问题。
-
读后再写是否可能被并发请求覆盖。
-
扣库存、扣余额、发权益是否具有幂等设计。
-
是否需要唯一约束防止重复插入。
-
批量更新是否缺少 WHERE 条件或范围过宽。
-
事务里是否做了慢查询、外部请求或长时间计算,导致锁持有过久。
-
状态更新是否需要 WHERE status = current_status 这种条件防止重复流转。
这类问题 Codex 可以帮你找到风险位置,但最终要结合业务一致性要求决定是用事务、乐观锁、唯一约束、队列、补偿任务还是幂等表。
重点检查维度 6:分页、排序和统计口径
Dashboard 和后台系统里,很多慢查询来自列表分页和统计卡片。要让 Codex 把“页面要展示什么”和“数据库怎么查”关联起来。
-
分页是否使用过大的 OFFSET。
-
排序字段是否稳定,是否在相同 created_at 下使用 id 作为第二排序。
-
COUNT(*) 是否每次都实时扫大表。
-
统计卡片是否每次访问页面都实时聚合全量数据。
-
筛选条件和导出条件是否一致。
-
统计是否需要按租户、权限、角色、时间区间隔离。
Codex 输出报告模板
SQL 查询审查报告 ## 1. 查询位置 - 文件: - 函数 / 接口: - 页面 / 业务场景: ## 2. 查询意图 - 这条查询理论上要返回什么: - 当前 SQL 实际返回什么: ## 3. 问题清单 | 优先级 | 类型 | 问题 | 证据 | 影响 | 建议 | |---|---|---|---|---|---| | P0 | 安全 | | | | | | P1 | 正确性 | | | | | | P2 | 性能 | | | | | ## 4. 推荐修改 - 修改点 1: - 修改点 2: - 是否需要 migration: - 是否需要索引: ## 5. 验证方式 - 单元测试: - 集成测试: - EXPLAIN / EXPLAIN ANALYZE: - 慢查询日志: - 回归场景: ## 6. 需要人工确认 - 业务口径: - 数据量: - 权限边界: - 上线窗口和回滚方案:
把 SQL 审查规则写进 AGENTS.md
如果你的项目经常需要 Codex 检查 SQL,不要每次都重新写规则。OpenAI 官方最佳实践建议把稳定、重复的规则写进 AGENTS.md,让 Codex 在仓库任务中自动读取。
AGENTS.md ## SQL review guidelines When reviewing SQL, ORM queries, migrations, API routes, reports, dashboards, or data export tasks, always check: 1. Correctness - Verify tenantid / organizationid / workspaceid isolation. - Verify soft delete fields such as deletedat, archived, or disabled. - Verify status filters, time ranges, timezone handling, and test data exclusion. - Check JOINs for duplicate rows and incorrect aggregation. 2. Performance - Flag SELECT in large queries. - Flag missing pagination or deep OFFSET pagination. - Flag queries likely to cause full table scans, large sorts, or inefficient joins. - When suggesting indexes, explain the target query, column order, write overhead, and rollback plan. - Prefer EXPLAIN or EXPLAIN ANALYZE evidence when available. 3. Security - Never concatenate user input into SQL. - Prefer parameterized queries or ORM-safe query builders. - Dynamic columns, table names, sort fields, and sort directions must use allowlists. - Do not log sensitive SQL parameters. 4. N+1 and repeated queries - Inspect loops, resolvers, services, and repository methods for repeated database calls. - Estimate query count as data size grows. - Suggest batching, JOIN, include, preloading, caching, or pre-aggregation when appropriate. 5. Transactions and data consistency - Check updates to money, inventory, quotas, user roles, order status, and membership benefits for concurrency risks. - Recommend transactions, idempotency, unique constraints, optimistic locking, or state checks when needed. Done means: - Provide a prioritized issue list. - Include evidence and affected files. - Include safe fixes and validation steps. - Mark uncertain business rules as “needs human confirmation”.
适合交给 Codex 的 SQL 审查任务类型
| 任务 | 怎么交给 Codex | 产出 |
|---|---|---|
| 上线前接口检查 | 让 Codex 审查本次 PR 里新增或修改的查询。 | 风险清单、修复建议、测试项。 |
| 慢查询排查 | 提供慢查询日志和 EXPLAIN 输出。 | 性能瓶颈解释、索引建议、SQL 改写方案。 |
| Dashboard 查询体检 | 让 Codex 读取统计卡片、图表、列表接口。 | 统计口径问题、聚合优化、缓存建议。 |
| SQL 注入排查 | 让 Codex 搜索 raw query 和动态 SQL。 | 风险位置、修复方案、测试用例。 |
| ORM 查询优化 | 让 Codex 检查 Prisma、TypeORM、Sequelize 查询链。 | N+1、include、select、transaction 风险。 |
| 迁移前审查 | 让 Codex 检查 migration 和现有查询兼容性。 | 破坏性变更、回滚方案、索引影响。 |
常见错误
错误 1:只把一段 SQL 粘给 Codex
SQL 离开业务上下文后,很难判断是否正确。应该给 Codex 表结构、调用文件、业务规则、数据量和问题现象。
错误 2:让 Codex 直接修改生产查询
SQL 改动风险高。正确流程是先输出审查报告,再生成最小改动,再补测试,再跑执行计划,最后人工确认。
错误 3:看到“加索引”就照做
索引会增加写入和存储成本,还可能不是瓶颈。Codex 的索引建议必须配合真实查询、数据量、执行计划和写入频率判断。
错误 4:只查性能,不查结果口径
很多 SQL 问题不是慢,而是错。尤其是多租户、软删除、权限、退款、取消、测试数据和时间区间,很容易被漏掉。
错误 5:忽视动态排序和字段名
即使用了参数化查询,字段名、表名、排序方向这类动态拼接如果没有 allowlist,仍然可能造成安全或越权风险。
