了解EXPLAIN ANALYZE查询计划

时间:2018-10-16 18:07:50

标签: 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?它来自哪里?

我认为这可能与第二种排序操作有关,但是它们是完全不同的分支。

有什么办法知道表是否适合内存?计划表明正在使用多少内存,但我看不到它们是否表明所有内存都适合。

1 个答案:

答案 0 :(得分:1)

我不确定,但是我的猜测是“合并联接”仅消耗了“排序”节点中的5634行。

PostgreSQL执行是按需执行的,也就是说,只要上层节点需要,就从下层节点请求结果行。

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

这不是您的问题,但是为了加快查询速度,您需要在people (name)movies (title)上建立索引。

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