CodeGym /课程 /SQL SELF /查询性能分析入门

查询性能分析入门

SQL SELF
第 41 级, 课程 0
可用

先来个真实的故事。想象一下你在一个大型电商平台做开发。所有东西都很顺,就是有个小问题:月销售报表加载慢到爆,用户都能再下单一次了还没出来。你开始焦虑,你经理也焦虑,PostgreSQL 服务器像水壶一样快烧开了,这场面简直像世界末日。现在想象一下,如果你能一下子找到原因并搞定它,是不是很爽?

查询性能分析就像给你的 PostgreSQL 做体检。它帮你找到“瓶颈”(痛点),修好它们,让用户体验更好,系统资源也省下来。

PostgreSQL 里的查询到底是怎么跑的?

比如你写了个简单的查询:

SELECT * FROM products WHERE price > 100;

PostgreSQL 并不会立刻去查数据。它会先分析你的 SQL,想想怎么执行最合适,然后才开始干活。

查询执行的主要阶段:

  1. 解析。PostgreSQL 检查你的 SQL 有没有语法错误,然后转成中间表示。
  2. 优化。查询优化器会评估多种执行方式,选一个“最便宜”的(时间和资源消耗最小)。
  3. 执行。服务器按选好的计划去查数据。

啥叫“瓶颈”?

“瓶颈”就是让整个查询变慢的那一部分。比如有个操作突然特别耗时或者吃资源。比如 PostgreSQL 本来可以用索引,结果却做了全表扫描(Seq Scan),那查询就慢了。或者数据比预期多很多,服务器花大量时间在排序、合并、过滤上。

这些地方就是所谓的瓶颈——你得优先找出来优化。

查询性能分析工具

PostgreSQL 有几个很强的工具,帮你定位查询里的问题:

  1. EXPLAIN 和 EXPLAIN ANALYZE。 这些命令能让你看到 PostgreSQL 打算怎么执行查询,甚至可以实际跑一下,测测真实性能。
  • EXPLAIN:只显示执行计划,不真的跑查询。
  • EXPLAIN ANALYZE:实际执行查询,并显示真实的执行计划和时间数据。

EXPLAIN 的用法示例:

EXPLAIN SELECT * FROM products WHERE price > 100;

输出:

Seq Scan on products  (cost=0.00..35.50 rows=5 width=72)
  Filter: (price > 100)

这里能看到,查询用了“Seq Scan”——全表扫描,对于大表来说效率很低。

  1. pg_stat_statements。 这是个额外的扩展,能记录所有执行过的查询。它能告诉你:
  • 服务器上都执行了哪些查询。
  • 每个查询花了多少时间。
  • 每个查询返回了多少行、用了多少资源。

要启用 pg_stat_statements,你得:

  1. 启用扩展:
CREATE EXTENSION pg_stat_statements;
  1. 配置 PostgreSQL: 在 postgresql.conf 文件里加上:
   shared_preload_libraries = 'pg_stat_statements'
   pg_stat_statements.track = all
  1. 重启 PostgreSQL。

现在你可以分析查询了:

SELECT * FROM pg_stat_statements ORDER BY total_time DESC LIMIT 5;

这会显示耗时最多的 5 个查询,按总执行时间降序排列。

  1. 慢查询日志。 你可以让 PostgreSQL 把执行太久(比如超过 1 秒)的查询写进日志文件。

在 postgresql.conf 里设置:

log_min_duration_statement = 1000  # 毫秒(1 秒)

现在慢查询就会被写进 PostgreSQL 日志了。

分析性能时关注的主要指标

分析查询性能时,重点看这些核心指标:

  1. 执行时间。就是查询跑完用了多久,越快越好。
  2. 行数。如果你的查询返回或扫描的行比你预期的多,可能有问题。
  3. 索引使用。如果本该用索引的查询却做了全表扫描(Seq Scan),那就该优化了。
  4. 缓冲区和磁盘操作。频繁访问磁盘的查询比用内存的数据慢多了。

这些知识怎么用?

例子 1:慢查询

你写了个查所有价格大于 100 的商品的 SQL:

SELECT * FROM products WHERE price > 100;
你发现查询很慢。用 EXPLAIN 一看:
Seq Scan on products  (cost=0.00..35.50 rows=5 width=72)
  Filter: (price > 100)

问题:查询做了全表扫描,因为 price 字段没有索引。

解决方法:

建个索引:

CREATE INDEX idx_price ON products(price);

现在查询会用 Index Scan:

Index Scan using idx_price on products  (cost=0.15..8.25 rows=5 width=72)
  Index Cond: (price > 100)

例子 2:用 pg_stat_statements 找慢查询

用这个命令:

SELECT query, total_time, calls
FROM pg_stat_statements
ORDER BY total_time DESC
LIMIT 1;

你发现有个查询特别耗时。用 EXPLAIN ANALYZE 打开它,优化一下,速度就上来了。

等你开始用 EXPLAIN、pg_stat_statements 等工具,你的查询会飞快,你的 PostgreSQL 服务器也会像瑞士手表一样稳。下一讲我们会深入聊聊 EXPLAIN 的参数,比如 cost、rows 和 width,让你能像看小说一样读懂执行计划。

2
任务
SQL SELF, 第 41 级, 课程 0
已锁定
使用 EXPLAIN 分析查询执行计划
使用 EXPLAIN 分析查询执行计划
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION