postgresql - 了解 EXPLAIN ANALYZE 查询计划

标签 postgresql sql-execution-plan

我有以下输出

Merge Join (cost=31843.55..32194.92 rows=30215 width=36)
           (actual time=496.720..510.071 rows=38381 loops=1)
  Merge Cond: (movies.year = people.birth_year)
  -> Sort (cost=9905.45..9918.62 rows=5268 width=22)
     (actual time=151.781..152.690 rows=5634 loops=1) // <---- !!!! LOOKING HERE !!!!
       Sort Key: movies.year
       Sort Method: quicksort Memory: 729kB
     -> Seq Scan on movies (cost=0.00..9579.81 rows=5268 width=22)
        (actual time=145.826..149.340 rows=7640 loops=1) // <---- !!!! LOOKING HERE !!!!
          Filter: (title > ’y’::text)
          Rows Removed by Filter: 456425 // <---- !!!! LOOKING HERE !!!!
  -> Sort (cost=21936.87..21953.89 rows=6808 width=18)
     (actual time=344.918..347.980 rows=38465 loops=1)
       Sort Key: people.birth_year
       Sort Method: quicksort Memory: 423kB
     -> Seq Scan on people (cost=0.00..21503.44 rows=6808 width=18)
        (actual time=341.883..343.847 rows=4151 loops=1)
          Filter: (name > ’zeke’::text)
          Rows Removed by Filter: 1099324
Planning time: 0.450 ms
Execution time: 511.988 ms

我想知道 title > 'y' 的选择性估计。
该计划显示 Rows Removed by Filter: 456425

我们拥有的总行数是 464065

由于过滤器删除了 456425 行,我们选择 464065 - 456425 = 7640 行,在 Seq Scan 行中提到。

但是为什么最上面的 Sort 显示实际行号为 5634?它来自哪里?

我以为可能跟第二个排序操作有关,但那是完全不同的分支。

有什么方法可以知道表是否适合内存?计划指示正在使用多少内存,但我没有看到它们指示所有这些是否适合内存。

最佳答案

我不确定,但我的猜测是“Merge Join”仅消耗了“Sort”节点的 5634 行。

PostgreSQL 执行“按需”工作,也就是说,只要上层节点需要,就会从下层节点请求结果行。

虽然“排序”确实需要“序列扫描”中的所有行,但合并连接可能在读取所有可用的已排序行之前完成。

那不是你的问题,但为了加快查询速度,你需要 people (name)movies (title) 的索引。

要知道您的数据是否被缓存,请使用 EXPLAIN (ANALYZE, BUFFERS)。然后您会看到在缓存中找到的 block 数(命中)和从操作系统读取的 block 数(读取)。但是请注意,“读取”数据可能来自文件系统缓存。

关于postgresql - 了解 EXPLAIN ANALYZE 查询计划,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52841543/

相关文章:

sql - PostgreSQL 中按数组重叠分组

postgresql - Postgres 对一个非常简单的 SELECT x ... ORDER BY x 进行 Seq Scan 而不是 Index Only Scan

oracle-sqldeveloper - 在 SQL Developer 中使用解释计划时出现 "Commit prior transaction"

postgresql - 在 docker 中使用 pg_dump 出现“没有现有的本地集群适合”错误

sql - UNION 子查询的奇怪行为,为什么?

oracle - 如何让 v$sql_plan 中的游标保持更长时间的事件

MySQL LEFT JOINS顺序,如何理解正确的算法

sql - 解释分析语句中的循环是什么意思?

postgresql - 获取 Postgresql SELECT 查询中所有已用表的列表

java - 连接到 JDBC 事务的开始