用 AI Agent 与 Postgres MCP 从概念到上线:电影评分网站性能调优实战拆解
2026/9/17 14:05:32 网站建设 项目流程

用 AI Agent 与 Postgres MCP 从概念到上线:电影评分网站性能调优实战拆解

【免费下载链接】klavisKlavis AI: MCP integration platforms that let AI agents use tools reliably at any scale项目地址: https://gitcode.com/GitHub_Trending/kl/klavis

本篇技术指南基于 Klavis 仓库中收录的 Postgres MCP 服务器(上游项目名为 Postgres MCP Pro,位于 mcp_servers/postgres)及其官方实战案例 movie-app.md,完整复盘一个"电影评分网站从零到上线"的 AI 编码过程:先用 AI 快速生成原型,再用 MCP 工具让 AI 像资深 DBA 一样诊断慢查询、优化索引、修复数据问题。读完本文,你将掌握如何把get_top_queriesanalyze_db_healthanalyze_query_indexes等 MCP 工具编排进 AI 编码工作流,并理解这些工具背后的数据库调优原理与源码实现。

案例背景:一次真实的 AI 编码马拉松

该案例的设定非常贴近一线开发者的真实工作场景:

  • 数据源:使用 IMDB 公开数据集(含影片基础信息title_basics、演职人员name_basics等多张表)构建一个电影评分网站。
  • AI 工具链:Replit 负责快速原型;Cursor 作为 AI 编码代理;Postgres MCP Pro 充当 Cursor 的"Postgres 专家",随时回答数据库相关问题。
  • 最终目标:让用户能按移动端友好的页面浏览每部电影的完整 IMDB 数据,对电影进行 1–5 星评分,并查看高分电影榜单。

整个案例分为四个阶段,覆盖了从"能跑"到"能上线"的完整链路:创建原型 → 修复性能 → 修复页面缺陷 → 修正排序逻辑。下面逐一拆解。

第一步:Replit 快速原型——一小时"能跑",但很慢

团队用 Replit 构建初始原型,提示词如下:

Create a web app based on flask, python and SQAlchemy ORM. It's website that uses the schema from the public IMDB dataset. Assume I've imported the IMDB dataset as-is and add to that. I want people to be able to browse a mobile-friendly page for each movie, with all the IMDB data related to that movie. Additionally, people can rate each movie 1-5 and view top rated movies. The community and these ratings are one of the primary uses cases for the website.

结果:不到一小时就得到了一个具备评分、搜索、浏览、认证等功能的完整网站。AI 编码在原型阶段的价值非常明显。

但问题也随之而来——网站太慢了。AI Agent 生成了一堆 ORM 代码和"看起来合理"的索引,但实际性能并不达标。这正是 ORM 生成型 AI 的典型短板:它不知道真实数据分布,也无法验证自己写的查询和索引在真实负载下是否高效。于是团队切换到 Cursor + Postgres MCP Pro 组合,进入调优阶段。

第二步:用 Postgres MCP 诊断并修复查询性能

对 Cursor 的提示词非常简洁:

My app is slow! Look for opportunities to speed up by improving queries, indexes or caching. For db changes use migration scripts I can apply later.

AI Agent 随后做了一系列工作,其中数据库侧的诊断链路完全由 Postgres MCP Pro 的工具支撑:

  1. 探索 schema 与代码,识别潜在的问题查询;
  2. 调用 MCP 工具诊断get_top_queries(找出最慢的查询)、analyze_db_health(全面体检)、analyze_query_indexes(为具体查询推荐索引);
  3. 添加多个索引提升查询性能;
  4. 移除未使用、臃肿的索引,回收存储空间;
  5. 为昂贵查询和图片加载增加缓存
  6. 生成迁移脚本,供后续在数据库上执行。

最终 AI Agent 在约 2.5 分钟内产出了一个完整的 Pull Request,并总结了预期影响:

  • 文本搜索快 10–100 倍;
  • 页面加载快 2–5 倍;
  • 数据库负载显著下降;
  • 外部 API 调用减少约 90%。

源码视角:get_top_queries 是怎么"找慢查询"的

get_top_queries的实现位于 top_queries_calc.py。它依赖pg_stat_statements扩展统计的查询执行数据,支持两种排序口径:

  • 按时间排序get_top_queries_by_time):可按total_exec_time(总执行时间)或mean_exec_time(单次平均执行时间)降序取前 N 条。该实现在 PostgreSQL 13+ 与 12 及以下版本间自动适配列名(*_time*_exec_time),见 top_queries_calc.py;
  • 按资源占比排序get_top_resource_queries,默认口径resources):不仅看执行时间,还综合了共享缓冲区命中/读取、脏块、WAL 字节数等指标,用窗口函数计算每个查询占总资源的分数,超过 5% 阈值的即视为资源大户,见 top_queries_calc.py。

从 server.py 可以看到该工具对外暴露的参数:sort_byresources/total_time/mean_time,默认resources)与limit(默认 10)。这正是案例中 Agent 定位"问题查询"的入口。

源码视角:analyze_db_health 体检了什么

analyze_db_health由 database_health.py 中的DatabaseHealthTool实现,接受一个health_type参数(默认all),支持八类检查:

检查项对应计算模块关注的问题
indexindex_health_calc.py无效索引、重复索引、索引膨胀(bloat)、未使用索引
connectionconnection_health_calc连接数及其利用率,预防连接耗尽
vacuumvacuum_health_calc事务 ID 回卷(wraparound)风险,防止数据库停止写入
sequencesequence_health_calc接近最大值、即将溢出的序列
replicationreplication_calc主备延迟、复制槽使用情况
bufferbuffer_health_calc表与索引的缓冲缓存命中率
constraintconstraint_health_calc无效约束(数据加载或恢复场景可能产生)

例如索引健康检查会找出"被另一个索引完全覆盖"的冗余索引,这正是案例中"移除未使用和臃肿的索引"的判定依据。README 的技术说明指出,这些健康检查改编自 PgHero 的实现,详见 README.md。

源码视角:索引推荐背后的工业级算法

analyze_query_indexes/analyze_workload_indexes是性能调优的核心,其实现分两层:

  • index_opt_base.py 定义了调优框架:工作负载来源支持"显式传入查询列表 / SQL 文件 /pg_stat_statements统计"四种途径;单次最多分析 10 条查询(MAX_NUM_INDEX_TUNING_QUERIES = 10,见 index_opt_base.py);从统计取工作负载时,默认要求calls >= 50且平均耗时>= 5ms
  • dta_calc.py 的DatabaseTuningAdvisor实现了"种子 + 贪心"搜索:默认单次分析最长 30 秒、索引最多 3 列、改进低于 10% 即停止。其核心思路来自微软 SQL Server 的 Anytime Algorithm(随时算法)。

搜索过程使用hypopg扩展做"假设索引"模拟:创建虚拟索引,再通过EXPLAIN观察 Postgres 优化器在真实成本模型下的计划变化,从而在不真正建索引的前提下评估收益。README 还描述了成本效益权衡:默认要求性能提升的对数(log10)达到空间代价对数差的 2 倍,即"允许 100 倍性能提升换取最多 10 倍空间增长"(详见 README.md)。案例中 Agent 能同时给出"加哪些索引"和"删哪些索引",正是这套成本模型在起作用。

第三步:修复空白的电影详情页——让 Agent"自己发现数据问题"

性能修好后,页面还有功能缺陷:电影详情页一片空白。提示词:

The movie details page looks awful. No cast/crew. Are we missing the data or is the query wrong? The ratings looks misplaced. move it closer to the title. Do we have additional data we can include like a description? Check the schema.

Agent 的处理过程体现了"数据驱动"的排查思路:

  1. 用 Postgres MCP 检查 schema 并与代码比对,判断是缺数据还是查询写错;
  2. 修复路由中的查询,补上对name_basics表的 JOIN(该表存有演职人员信息);
  3. title_basics中发现可用字段(类型、片长、上映年份等),新增了 About 区域丰富页面内容。

随后团队进一步追问:"Am I missing any data?"——Agent 直接运行 SQL 查询验证,确认确实缺少 cast/crew 数据,并重写了一个更可靠的数据导入脚本(原导入脚本在遇到错误时会直接中止,导致数据不完整)。这一步的价值在于:Agent 没有凭记忆假设,而是通过工具查询真实 schema 和数据分布来得出结论,这正是"结果基于现实而非幻觉"的典型示范。

从工具链角度看,这里用到的能力在 server.py 中有完整实现:list_schemas列出全部 schema(区分系统 schema 与用户 schema)、list_objects按类型列出表/视图/序列/扩展、get_object_details返回指定表的列、约束、索引明细。Agent 正是通过这三个工具完成"schema 智能"层面的探索。

第四步:修正 Top Rated 排序——用数据分布确定参数

高分榜单页显示的居然是 "Sisters of the Shrink 4"、"Zhuchok" 这类冷门片,显然有问题。提示词:

How are the top-rated sorted? It seems random. Do we have data in those tables? Is the query it uses working?

Agent 检查数据与代码后定位到根因:排序查询对num_votes(投票数)没有设置下限——一部只有 1 人打了 5 星的电影,会排在万人评分 9.0 的大片前面。于是团队继续追问:

help me find a good minimum of reviews

Agent 通过分析投票数的数据分布和抽样结果,最终确定1 万票(10K votes)作为最低门槛能得到最佳榜单质量。这个"用数据说话"的决策过程,正是把数据库分析与业务逻辑连接起来的典型做法——也是案例作者感叹"结果扎根于现实而非幻觉"的原因。

这个环节虽然不直接调用索引工具,但它展示了 MCP 工具在数据探索(execute_sql跑分布查询)中的价值:Agent 可以反复查询、验证、再决策,而不必依赖猜测。

如何复现这套工作流

如果你也想在自己的项目里复现"AI 编码 + Postgres 专家"的组合,可以按以下步骤搭建。

安装 Postgres MCP 服务器

官方推荐两种方式,任选其一(详见 README.md):

方式一:Docker

docker pull crystaldba/postgres-mcp

方式二:Python(pipx 或 uv)

pipx install postgres-mcp # 或 uv pip install postgres-mcp

Docker 镜像会自动处理主机名映射:macOS/Windows 自动使用host.docker.internal,Linux 自动使用172.17.0.1等宿主机地址。

配置到 AI 客户端

以 Cursor 为例(Claude Desktop 等客户端的配置格式类似),在 MCP 配置文件中添加:

{ "mcpServers": { "postgres": { "command": "docker", "args": ["run", "-i", "--rm", "-e", "DATABASE_URI", "crystaldba/postgres-mcp", "--access-mode=unrestricted"], "env": { "DATABASE_URI": "postgresql://username:password@localhost:5432/dbname" } } } }

--access-mode有两个取值(对应 server.py 中的AccessMode枚举):

  • unrestricted(默认):完全读写权限,适合开发环境。execute_sql工具被标记为破坏性(destructiveHint),AI 可自由执行任意 SQL;
  • restricted:只读事务 + 30 秒执行超时,适合生产环境。此时execute_sql变为只读语义(见 server.py)。

关于 restricted 模式的安全机制值得一提:由于 Postgres 本身不支持把连接置于只读模式,Postgres MCP Pro 在只读事务之上,用 pglast)。这是防止 LLM 生成的 SQL 绕过只读限制(如ROLLBACK; DROP TABLE users;)的关键防线。

启用两个必备扩展

索引调优与慢查询分析依赖两个扩展(详见 README.md):

CREATE EXTENSION IF NOT EXISTS pg_stat_statements; -- 查询执行统计 CREATE EXTENSION IF NOT EXISTS hypopg; -- 假设索引模拟

云托管数据库(AWS RDS、Azure SQL、Google Cloud SQL)通常已内置,直接CREATE EXTENSION即可;自建 Postgres 可能需要将pg_stat_statements加入shared_preload_libraries,并用系统包管理器安装hypopg

可直接套用的提问模板

场景提示词
全面体检Check the health of my database and identify any issues.
慢查询分析What are the slowest queries in my database? And how can I speed them up?
性能优化My app is slow. How can I make it faster?
索引推荐Analyze my database workload and suggest indexes to improve performance.
单查询优化Help me optimize this query: SELECT * FROM orders JOIN customers ON ...

结语:把数据库专家"装进" AI 编码循环

回顾这个案例,最值得借鉴的不是某个具体索引,而是工作流的闭环:AI 生成代码 → MCP 工具提供真实数据库证据(慢查询、健康体检、假设索引模拟)→ AI 依据证据修正代码和数据 → 人工通过迁移脚本掌控变更。Postgres MCP Pro 的价值在于把"LLM 的推理能力"与"确定性的数据库算法"(Anytime 索引调优、PgHero 健康检查、pglast 安全校验)组合在一起,让 AI 的判断有据可依。

如果你想深入探索该服务器的更多技术细节,可以从这几个入口继续:

  • 服务器入口与全部工具注册:server.py
  • 索引调优框架与候选生成:index_opt_base.py、dta_calc.py
  • 慢查询与健康检查实现:top_queries_calc.py、database_health.py
  • 只读安全执行:safe_sql.py
  • 完整功能与 FAQ:README.md

【免费下载链接】klavisKlavis AI: MCP integration platforms that let AI agents use tools reliably at any scale项目地址: https://gitcode.com/GitHub_Trending/kl/klavis

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询