> On Jul 7, 2018, at 12:03 AM, Amit Kapila <amit.kapil...@gmail.com> wrote:
> 
> On Sat, Jul 7, 2018 at 7:45 AM, Amit Kapila <amit.kapil...@gmail.com 
> <mailto:amit.kapil...@gmail.com>> wrote:
>> On Sat, Jul 7, 2018 at 12:44 AM, Robert Haas <robertmh...@gmail.com> wrote:
>>> On Fri, Jul 6, 2018 at 9:44 AM, Amit Kapila <amit.kapil...@gmail.com> wrote:
>>>> I have tried this idea, but it doesn't completely solve the problem.
>>>> The problem is that nodes below LIMIT won't get a chance to accumulate
>>>> the stats as they won't be able to call InstrStopNode.
>>> 
>>> I'm not sure I understand.  Why not?  I see that we'd need to insert
>>> an extra call to InstrStopNode() if we were stopping the node while it
>>> was running, because then InstrStartNode() would have already been
>>> done, but the corresponding call to InstrStopNode() would not have
>>> been done.  But I'm not sure how that would happen in this case.  Can
>>> you explain further?
>>> 
>> 
>> Okay, let me try.   The code flow is that for each node we will call
>> InstrStartNode()->ExecProcNodeReal()->InstrStopNode().  Now let's say
>> we have to execute a plan Limit->Gather-> Parallel SeqScan.  In this,
>> first for Limit node, we will call InstrStartNode() and
>> ExecProcNodeReal() and then for Gather we will call InstrStartNode(),
>> ExecProcNodeReal() and InstrStopNode().  Now, Limit node decides that
>> it needs to shutdown all the nodes (ExecShutdownNode) and after that
>> it will call InstrStopNode() for Limit node.  So, in this flow after
>> shutting down nodes, we never get chance for Gather node to use stats
>> collected during ExecShutdownNode.
>> 
> 
> I went ahead and tried the solution which I had mentioned yesterday,
> that is to allow ExecShutdownNode to count stats.  Apart from fixing
> this problem, it will also fix the problem with Gather Merge as
> reported by Adrien [1], because now Gather Merge will also get a
> chance to count stats after shutting down workers.
> 
> Note that, I have changed the location of InstrStartParallelQuery in
> ParallelQueryMain so that the buffer usage stats are accumulated only
> for the plan execution which is what we do for instrumentation
> information as well.  If we don't do that, it will count some
> additional stats for ExecutorStart which won't match with what we have
> in Instrumentation structure of each node.

I tried running the below on both 11beta2 and HEAD with the patch
applied:

        CREATE UNLOGGED TABLE t1 (c1 int);
        INSERT INTO t1 SELECT generate_series(1,100000000);
        /** restart PostgreSQL */
        EXPLAIN (analyze,buffers,timing off,costs off)
        SELECT count(*) FROM t1;
        /** repeat above two queries */

I have identical postgresql.conf files on both instances as well.

11beta2
======
    buffers=# explain (analyze,buffers,timing off,costs off) select count(*)
    from t1;
                                    QUERY PLAN
    --------------------------------------------------------------------------
     Finalize Aggregate (actual rows=1 loops=1)
       Buffers: shared read=63175
       ->  Gather (actual rows=7 loops=1)
             Workers Planned: 6
             Workers Launched: 6
             Buffers: shared read=63175
             ->  Partial Aggregate (actual rows=1 loops=7)
                   Buffers: shared read=442478
                   ->  Parallel Seq Scan on t1 (actual rows=14285714 loops=7)
                         Buffers: shared read=442478
     Planning Time: 1.422 ms
     Execution Time: 3214.407 ms
    (12 rows)

    buffers=# explain (analyze,buffers,timing off,costs off) select count(*)
    from t1;
                                    QUERY PLAN
    --------------------------------------------------------------------------
     Finalize Aggregate (actual rows=1 loops=1)
       Buffers: shared hit=27 read=64960
       ->  Gather (actual rows=7 loops=1)
             Workers Planned: 6
             Workers Launched: 6
             Buffers: shared hit=27 read=64960
             ->  Partial Aggregate (actual rows=1 loops=7)
                   Buffers: shared hit=224 read=442254
                   ->  Parallel Seq Scan on t1 (actual rows=14285714 loops=7)
                         Buffers: shared hit=224 read=442254
     Planning Time: 0.080 ms
     Execution Time: 3774.091 ms
    (12 rows)

HEAD
=====
    buffers=# explain (analyze,buffers,timing off,costs off) select count(*)
    from t1;
                                    QUERY PLAN
    --------------------------------------------------------------------------
     Finalize Aggregate (actual rows=1 loops=1)
       Buffers: shared read=442478
       ->  Gather (actual rows=7 loops=1)
             Workers Planned: 6
             Workers Launched: 6
             Buffers: shared read=442478
             ->  Partial Aggregate (actual rows=1 loops=7)
                   Buffers: shared read=442478
                   ->  Parallel Seq Scan on t1 (actual rows=14285714 loops=7)
                         Buffers: shared read=442478
     Planning Time: 1.594 ms
     Execution Time: 6207.799 ms
    (12 rows)

    buffers=# explain (analyze,buffers,timing off,costs off) select count(*)
    from t1;
                                    QUERY PLAN
    --------------------------------------------------------------------------
     Finalize Aggregate (actual rows=1 loops=1)
       Buffers: shared hit=224 read=442254
       ->  Gather (actual rows=7 loops=1)
             Workers Planned: 6
             Workers Launched: 6
             Buffers: shared hit=224 read=442254
             ->  Partial Aggregate (actual rows=1 loops=7)
                   Buffers: shared hit=224 read=442254
                   ->  Parallel Seq Scan on t1 (actual rows=14285714 loops=7)
                         Buffers: shared hit=224 read=442254
     Planning Time: 0.074 ms
     Execution Time: 5006.395 ms
    (12 rows)

Notice the “read” numbers just before the “Finalize Aggregate” is much
higher, and there appears to be a performance hit.

Jonathan

Attachment: signature.asc
Description: Message signed with OpenPGP

Reply via email to