分析:为什么查询可能需要这么长时间,似乎成本很低?

问题描述 投票:2回答:1

我有这些结果用于分析一个简单的查询,该查询不会从少于200条记录的表中返回超过150条记录,因为我有一个存储最新值的表,其他字段是数据的FK。

更新:稍后查看相同查询的新结果。该网站不公开和/或现在应该没有用户,因为它正在开发中。

 explain analyze
SELECT lv.station_id,
    s.name AS station_name,
    s.latitude,
    s.longitude,
    s.elevation,
    lv.element_id,
    e.symbol AS element_symbol,
    u.symbol,
    e.name AS element_name,
    lv.last_datetime AS datetime,
    lv.last_value AS valor,
    s.basin_id,
    s.municipality_id
   FROM (((element_station lv /*350 records*/
     JOIN stations s ON ((lv.station_id = s.id))) /*40 records*/
     JOIN elements e ON ((lv.element_id = e.id))) /*103 records*/
     JOIN units u ON ((e.unit_id = u.id))) /* 32 records */
  WHERE s.id = lv.station_id AND e.id = lv.element_id AND lv.interval_id = 6 and
lv.last_datetime >= ((now() - '06:00:00'::interval) - '01:00:00'::interval)

我已经尝试了VACUUM,之后有些人得救了,但有一段时间后它再次上升。我已经在字段上实现了索引。

Nested Loop  (cost=0.29..2654.66 rows=1 width=92) (actual time=1219.390..35296.253 rows=157 loops=1)
  Join Filter: (e.unit_id = u.id)
  Rows Removed by Join Filter: 4867
  ->  Nested Loop  (cost=0.29..2652.93 rows=1 width=92) (actual time=1219.383..35294.083 rows=157 loops=1)
        Join Filter: (lv.element_id = e.id)
        Rows Removed by Join Filter: 16014
        ->  Nested Loop  (cost=0.29..2648.62 rows=1 width=61) (actual time=1219.301..35132.373 rows=157 loops=1)
              ->  Seq Scan on element_station lv  (cost=0.00..2640.30 rows=1 width=20) (actual time=1219.248..1385.517 rows=157 loops=1)
                    Filter: ((interval_id = 6) AND (last_datetime >= ((now() - '06:00:00'::interval) - '01:00:00'::interval)))
                    Rows Removed by Filter: 168
              ->  Index Scan using stations_pkey on stations s  (cost=0.29..8.31 rows=1 width=45) (actual time=3.471..214.941 rows=1 loops=157)
                    Index Cond: (id = lv.station_id)
        ->  Seq Scan on elements e  (cost=0.00..3.03 rows=103 width=35) (actual time=0.003..0.999 rows=103 loops=157)
  ->  Seq Scan on units u  (cost=0.00..1.32 rows=32 width=8) (actual time=0.002..0.005 rows=32 loops=157)
Planning time: 8.312 ms
Execution time: 35296.427 ms

更新,今晚运行相同的查询;没有变化:

Sort  (cost=601.74..601.88 rows=55 width=92) (actual time=1.822..1.841 rows=172 loops=1)
  Sort Key: lv.last_datetime DESC
  Sort Method: quicksort  Memory: 52kB
  ->  Nested Loop  (cost=11.60..600.15 rows=55 width=92) (actual time=0.287..1.680 rows=172 loops=1)
        ->  Hash Join  (cost=11.31..248.15 rows=55 width=51) (actual time=0.263..0.616 rows=172 loops=1)
              Hash Cond: (e.unit_id = u.id)
              ->  Hash Join  (cost=9.59..245.60 rows=75 width=51) (actual time=0.225..0.528 rows=172 loops=1)
                    Hash Cond: (lv.element_id = e.id)
                    ->  Bitmap Heap Scan on element_station lv  (cost=5.27..240.25 rows=75 width=20) (actual time=0.150..0.359 rows=172 loops=1)
                          Recheck Cond: ((last_datetime >= ((now() - '06:00:00'::interval) - '01:00:00'::interval)) AND (interval_id = 6))
                          Heap Blocks: exact=22
                          ->  Bitmap Index Scan on element_station_latest  (cost=0.00..5.25 rows=75 width=0) (actual time=0.136..0.136 rows=226 loops=1)
                                Index Cond: ((last_datetime >= ((now() - '06:00:00'::interval) - '01:00:00'::interval)) AND (interval_id = 6))
                    ->  Hash  (cost=3.03..3.03 rows=103 width=35) (actual time=0.062..0.062 rows=103 loops=1)
                          Buckets: 1024  Batches: 1  Memory Usage: 15kB
                          ->  Seq Scan on elements e  (cost=0.00..3.03 rows=103 width=35) (actual time=0.006..0.031 rows=103 loops=1)
              ->  Hash  (cost=1.32..1.32 rows=32 width=8) (actual time=0.019..0.019 rows=32 loops=1)
                    Buckets: 1024  Batches: 1  Memory Usage: 10kB
                    ->  Seq Scan on units u  (cost=0.00..1.32 rows=32 width=8) (actual time=0.003..0.005 rows=32 loops=1)
        ->  Index Scan using stations_pkey on stations s  (cost=0.29..6.39 rows=1 width=45) (actual time=0.005..0.006 rows=1 loops=172)
              Index Cond: (id = lv.station_id)
Planning time: 2.390 ms
Execution time: 2.009 ms
postgresql query-performance
1个回答
1
投票

问题是element_station上顺序扫描中行数的差异。自动分析已启动并计算表的新统计数据或更改的数据。

问题可能是PostgreSQL不知道结果

((now() - '06:00:00'::interval) - '01:00:00'::interval)

在查询计划时间。

如果您可以这样做,请分两步完成:首先,计算上面的表达式(在PostgreSQL或客户端)。然后以结果作为常量运行查询。这将使PostgreSQL更容易估计结果计数。

© www.soinside.com 2019 - 2024. All rights reserved.