PostgreSQL中的EXPLAIN ANALYZE:对查询性能有影响吗?

时间:2019-01-18 10:24:30

标签: postgresql postgresql-performance

每次在PostgreSQL中的查询上运行EXPLAIN ANALYZE时,Execution time都会减少。为什么?

我需要在表上做一些索引,这样我就不能确定我的动作是否会提高性能。你向我推荐什么?

示例的连续执行结果说明(分析,缓冲区):

my_db=# explain (analyze, buffers)
SELECT COUNT(*) AS count
FROM my_view
WHERE creation_time >= '2019-01-18 00:00:00'
  AND creation_time <= '2019-01-18 09:43:36'
ORDER BY count DESC
LIMIT 10000;
                                                                                                                                   QUERY PLAN                                                               

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------
 Limit  (cost=2568854.23..2568854.23 rows=1 width=8) (actual time=24380.613..24380.614 rows=1 loops=1)
   Buffers: shared hit=14915 read=2052993, temp read=562 written=563
   ->  Sort  (cost=2568854.23..2568854.23 rows=1 width=8) (actual time=24380.611..24380.611 rows=1 loops=1)
         Sort Key: (count(*)) DESC
         Sort Method: quicksort  Memory: 25kB
         Buffers: shared hit=14915 read=2052993, temp read=562 written=563
         ->  Aggregate  (cost=2568854.21..2568854.22 rows=1 width=8) (actual time=24380.599..24380.599 rows=1 loops=1)
               Buffers: shared hit=14915 read=2052993, temp read=562 written=563
               ->  GroupAggregate  (cost=2568854.18..2568854.20 rows=1 width=28) (actual time=24339.455..24380.589 rows=40 loops=1)
                     Group Key: my_table.creation_time, my_table.some_field
                     Buffers: shared hit=14915 read=2052993, temp read=562 written=563
                     ->  Sort  (cost=2568854.18..2568854.18 rows=1 width=12) (actual time=24338.361..24357.171 rows=199309 loops=1)
                           Sort Key: my_table.creation_time, my_table.some_field
                           Sort Method: external merge  Disk: 4496kB
                           Buffers: shared hit=14915 read=2052993, temp read=562 written=563
                           ->  Gather  (cost=1000.00..2568854.17 rows=1 width=12) (actual time=23799.237..24142.217 rows=199309 loops=1)
                                 Workers Planned: 2
                                 Workers Launched: 2
                                 Buffers: shared hit=14915 read=2052993
                                 ->  Parallel Seq Scan on my_table  (cost=0.00..2567854.07 rows=1 width=12) (actual time=23796.695..24087.574 rows=66436 loops=3)
                                       Filter: (creation_time >= '2019-01-18 00:00:00+00'::timestamp with time zone) AND (creation_time <= '2019-01-18 09:43:36+00'::timestamp with time zone)
                                       Rows Removed by Filter: 21818095
                                       Buffers: shared hit=14915 read=2052993
 Planning time: 10.982 ms
 Execution time: 24381.544 ms
(25 rows)

my_db=# explain (analyze, buffers)
SELECT COUNT(*) AS count
FROM my_view
WHERE creation_time >= '2019-01-18 00:00:00'
  AND creation_time <= '2019-01-18 09:43:36'
ORDER BY count DESC
LIMIT 10000;
                                                                                                                                   QUERY PLAN                                                               

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------
 Limit  (cost=2568854.23..2568854.23 rows=1 width=8) (actual time=6836.247..6836.248 rows=1 loops=1)
   Buffers: shared hit=15181 read=2052727, temp read=562 written=563
   ->  Sort  (cost=2568854.23..2568854.23 rows=1 width=8) (actual time=6836.245..6836.246 rows=1 loops=1)
         Sort Key: (count(*)) DESC
         Sort Method: quicksort  Memory: 25kB
         Buffers: shared hit=15181 read=2052727, temp read=562 written=563
         ->  Aggregate  (cost=2568854.21..2568854.22 rows=1 width=8) (actual time=6836.232..6836.232 rows=1 loops=1)
               Buffers: shared hit=15181 read=2052727, temp read=562 written=563
               ->  GroupAggregate  (cost=2568854.18..2568854.20 rows=1 width=28) (actual time=6792.036..6836.221 rows=40 loops=1)
                     Group Key: my_table.creation_time, my_table.some_field
                     Buffers: shared hit=15181 read=2052727, temp read=562 written=563
                     ->  Sort  (cost=2568854.18..2568854.18 rows=1 width=12) (actual time=6790.807..6811.469 rows=199309 loops=1)
                           Sort Key: my_table.creation_time, my_table.some_field
                           Sort Method: external merge  Disk: 4496kB
                           Buffers: shared hit=15181 read=2052727, temp read=562 written=563
                           ->  Gather  (cost=1000.00..2568854.17 rows=1 width=12) (actual time=6271.571..6604.946 rows=199309 loops=1)
                                 Workers Planned: 2
                                 Workers Launched: 2
                                 Buffers: shared hit=15181 read=2052727
                                 ->  Parallel Seq Scan on my_table  (cost=0.00..2567854.07 rows=1 width=12) (actual time=6268.383..6529.416 rows=66436 loops=3)
                                       Filter: (creation_time >= '2019-01-18 00:00:00+00'::timestamp with time zone) AND (creation_time <= '2019-01-18 09:43:36+00'::timestamp with time zone)
                                       Rows Removed by Filter: 21818095
                                       Buffers: shared hit=15181 read=2052727
 Planning time: 0.570 ms
 Execution time: 6837.137 ms
(25 rows)

谢谢。

1 个答案:

答案 0 :(得分:0)

这是什么版本的PostgreSQL?

有两个问题:

  1. 缺少索引:

    <div class="form-group">
        <label for="reservation_id" class="col-md-4 control-label">Reservation</label>
        <div class="col-md-8">
            <select name="reservation_id" class="form-control">
                <option value="">select reservation</option>
                <?php 
                foreach($all_reservations as $reservation)
                {
                    $selected = ($reservation['id'] == $this->input->post('reservation_id')) ? ' selected="selected"' : "";
    
                    echo '<option value="'.$reservation['id'].'" '.$selected.'>'.$reservation['id'].'</option>';
                }
                ?>
            </select>
        </div>
    </div>
    
  2. CREATE INDEX ON my_table (creation_time); 时间的值分布统计信息不正确,这导致PostgreSQL严重低估了结果行的数量。

    这不是问题的直接原因,但是您应该调查那里发生的事情:

    • 如果creation改进了估算值,请参见该表的自动分析运行频率更高。

    • 如果ANALYZE my_table没有帮助,请收集更好的统计信息:

      ANALYZE my_table

使用ALTER TABLE my_table ALTER creation_time SET STATISTICS 1000; ANALYZE my_table; 观察到的执行时间减少可能是由于缓存效应所致。