Обсуждение: BUG #10404: auto_explain for EXPLAIN ANLYZE.

Поиск
Список
Период
Сортировка

BUG #10404: auto_explain for EXPLAIN ANLYZE.

От
katsumata.tomonari@po.ntts.co.jp
Дата:
The following bug has been logged on the website:

Bug reference:      10404
Logged by:          Tomonari Katsumata
Email address:      katsumata.tomonari@po.ntts.co.jp
PostgreSQL version: 9.3.4
Operating system:   CentOS 6.4 x86_64
Description:

Hi,

I'm testing auto_explain.
And I noticed that auto_explain has a strange behavior.

The settings for auto_explain are like below.

-------------------------------
testdb=# select name, setting from pg_settings where name like
'%auto_explain%';
                name                | setting
------------------------------------+---------
 auto_explain.log_analyze           | on
 auto_explain.log_buffers           | on
 auto_explain.log_format            | text
 auto_explain.log_min_duration      | 0
 auto_explain.log_nested_statements | off
 auto_explain.log_timing            | on
 auto_explain.log_verbose           | on
(7 rows)
-------------------------------

And then, I tested five cases.

-------------------------------
a.EXPLAIN ONLY
b.EXPLAIN ANALYZE
c.EXPLAIN ANALYZE BUFFERS
d.EXPLAIN ANALYZE BUFFERS-OFF
e.EXPLAIN ANALYZE TIMING
f.EXPLAIN ANALYZE TIMING-OFF
-------------------------------

The results of a to e are good, but the result of f is not good.
I thought "actual time" would be omitted from the result of EXPLAIN,
but it is there.
Is this an intentional thing? or bug?


The test results are below.

===============
a.EXPLAIN ONLY
===============
testdb=# explain select * from hoge where i = 3;
                      QUERY PLAN
------------------------------------------------------
 Seq Scan on hoge  (cost=0.00..40.00 rows=12 width=4)
   Filter: (i = 3)
(2 rows)

****************************************************************
LOG:  duration: 0.000 ms  plan:
    Query Text: explain select * from hoge where i = 3;
    Seq Scan on public.hoge  (cost=0.00..40.00 rows=12 width=4)
      Output: i
      Filter: (hoge.i = 3)
****************************************************************


=================
b.EXPLAIN ANALYZE
=================
testdb=# explain analyze select * from hoge where i = 3;
                                            QUERY PLAN

--------------------------------------------------------------------------------------------------
 Seq Scan on hoge  (cost=0.00..40.00 rows=12 width=4) (actual
time=23.484..23.484 rows=0 loops=1)
   Filter: (i = 3)
   Rows Removed by Filter: 1
 Total runtime: 25.275 ms
(4 rows)

****************************************************************
LOG:  duration: 23.488 ms  plan:
    Query Text: explain analyze select * from hoge where i = 3;
    Seq Scan on public.hoge  (cost=0.00..40.00 rows=12 width=4) (actual
time=23.484..23.484 rows=0 loops=1)
      Output: i
      Filter: (hoge.i = 3)
      Rows Removed by Filter: 1
      Buffers: shared hit=1
****************************************************************


=========================
c.EXPLAIN ANALYZE BUFFERS
=========================
testdb=# explain (analyze, buffers) select * from hoge where i = 3;
                                           QUERY PLAN

------------------------------------------------------------------------------------------------
 Seq Scan on hoge  (cost=0.00..40.00 rows=12 width=4) (actual
time=0.152..0.152 rows=0 loops=1)
   Filter: (i = 3)
   Rows Removed by Filter: 1
   Buffers: shared hit=1
 Total runtime: 0.326 ms
(5 rows)

****************************************************************
LOG:  duration: 0.155 ms  plan:
    Query Text: explain (analyze, buffers) select * from hoge where i = 3;
    Seq Scan on public.hoge  (cost=0.00..40.00 rows=12 width=4) (actual
time=0.152..0.152 rows=0 loops=1)
      Output: i
      Filter: (hoge.i = 3)
      Rows Removed by Filter: 1
      Buffers: shared hit=1
****************************************************************


=============================
d.EXPLAIN ANALYZE BUFFERS-OFF
=============================
testdb=# explain (analyze, buffers off) select * from hoge where i = 3;
                                           QUERY PLAN

------------------------------------------------------------------------------------------------
 Seq Scan on hoge  (cost=0.00..40.00 rows=12 width=4) (actual
time=0.024..0.024 rows=0 loops=1)
   Filter: (i = 3)
   Rows Removed by Filter: 1
 Total runtime: 1.407 ms
(4 rows)

****************************************************************
LOG:  duration: 0.026 ms  plan:
    Query Text: explain (analyze, buffers off) select * from hoge where i = 3;
    Seq Scan on public.hoge  (cost=0.00..40.00 rows=12 width=4) (actual
time=0.024..0.024 rows=0 loops=1)
      Output: i
      Filter: (hoge.i = 3)
      Rows Removed by Filter: 1
      Buffers: shared hit=1
****************************************************************


========================
e.EXPLAIN ANALYZE TIMING
========================
testdb=# explain (analyze, timing) select * from hoge where i = 3;
                                           QUERY PLAN

------------------------------------------------------------------------------------------------
 Seq Scan on hoge  (cost=0.00..40.00 rows=12 width=4) (actual
time=0.024..0.024 rows=0 loops=1)
   Filter: (i = 3)
   Rows Removed by Filter: 1
 Total runtime: 0.207 ms
(4 rows)

****************************************************************
LOG:  duration: 0.026 ms  plan:
    Query Text: explain (analyze, timing) select * from hoge where i = 3;
    Seq Scan on public.hoge  (cost=0.00..40.00 rows=12 width=4) (actual
time=0.024..0.024 rows=0 loops=1)
      Output: i
      Filter: (hoge.i = 3)
      Rows Removed by Filter: 1
      Buffers: shared hit=1
****************************************************************


============================
f.EXPLAIN ANALYZE TIMING-OFF
============================
testdb=# explain (analyze, timing off) select * from hoge where i = 3;
                                           QUERY PLAN

------------------------------------------------------------------------------------------------
 Seq Scan on hoge  (cost=0.00..40.00 rows=12 width=4) (actual
time=0.023..0.023 rows=0 loops=1)
   Filter: (i = 3)
   Rows Removed by Filter: 1
 Total runtime: 0.194 ms
(4 rows)

****************************************************************
LOG:  duration: 0.026 ms  plan:
    Query Text: explain (analyze, timing off) select * from hoge where i = 3;
    Seq Scan on public.hoge  (cost=0.00..40.00 rows=12 width=4) (actual
time=0.023..0.023 rows=0 loops=1)
      Output: i
      Filter: (hoge.i = 3)
      Rows Removed by Filter: 1
      Buffers: shared hit=1
****************************************************************


regards,
----------------------
Tomonari Katsumata

Re: BUG #10404: auto_explain for EXPLAIN ANLYZE.

От
Tom Lane
Дата:
katsumata.tomonari@po.ntts.co.jp writes:
> [ auto_explain changes the user-visible behavior of EXPLAIN ]
> Is this an intentional thing? or bug?

Yeah, that's a bug.  The code in explain.c is looking at whether it got
timing results, not whether it asked for them ...

            regards, tom lane

Re: BUG #10404: auto_explain for EXPLAIN ANLYZE.

От
Tomonari Katsumata
Дата:
Hi Tom,

Thank you for checking it.

(2014/05/20 20:51), Tom Lane wrote:
> katsumata.tomonari@po.ntts.co.jp writes:
>> [ auto_explain changes the user-visible behavior of EXPLAIN ]
>> Is this an intentional thing? or bug?
>
> Yeah, that's a bug. The code in explain.c is looking at whether it got
> timing results, not whether it asked for them ...
>
I made a patch for this bug.
Please see the attached patch.

According to my understanding,
explain.c flows like below.

ExplainOnePlan
- call ExecutorStart(explain_ExecutorStart)
- call ExecutorRun(explain_ExecutorRun)
- call ExecutorFinish(explain_ExecutorFinish)
- call ExplainPrintPlan *A*
- call ExecutorEnd(explain_ExecutorEnd) *B*

The query result is printed at *A*, and then
auto_explain log message is printed at *B*.

So I add a check in explain_ExecutorFinish if the query has
"EXPLAIN ANALYZE TIMING OFF" or not to supress timing output
at *A*.
And I add a check in explain_ExecutorEnd if the setting of
auto_explain need timing information or not.

To distinguish "EXPLAIN ANALYZE TIMING OFF" or not, I use
queryDesc->instrument_options has INSTRUMENT_ROWS flag or not.
And also to distinguish if auto_explain needs timing info or not,
I use queryDesc->instrument_options has INSTRUMENT_TIMING flag or not.

This works fine, but I'm not sure I should to use INSTRUMENT_ROWS flag
for this. Because it seems that the flags is used but not referenced
from anywhere in current code.
Will this flag be obsoleted?


regards,
--------------------
Tomonari Katsumata


Вложения

Re: BUG #10404: auto_explain for EXPLAIN ANLYZE.

От
Tomonari Katsumata
Дата:
Hi Tom,

You fixed this problem already.
Sorry for confusing you...
please forget my last mail.

Thank you for alot!

(2014/05/21 11:37), Tomonari Katsumata wrote:
> Hi Tom,
>
> Thank you for checking it.
>
> (2014/05/20 20:51), Tom Lane wrote:
>> katsumata.tomonari@po.ntts.co.jp writes:
>>> [ auto_explain changes the user-visible behavior of EXPLAIN ]
>>> Is this an intentional thing? or bug?
>>
>> Yeah, that's a bug. The code in explain.c is looking at whether it got
>> timing results, not whether it asked for them ...
>>
> I made a patch for this bug.
> Please see the attached patch.
>
> According to my understanding,
> explain.c flows like below.
>
> ExplainOnePlan
> - call ExecutorStart(explain_ExecutorStart)
> - call ExecutorRun(explain_ExecutorRun)
> - call ExecutorFinish(explain_ExecutorFinish)
> - call ExplainPrintPlan *A*
> - call ExecutorEnd(explain_ExecutorEnd) *B*
>
> The query result is printed at *A*, and then
> auto_explain log message is printed at *B*.
>
> So I add a check in explain_ExecutorFinish if the query has
> "EXPLAIN ANALYZE TIMING OFF" or not to supress timing output
> at *A*.
> And I add a check in explain_ExecutorEnd if the setting of
> auto_explain need timing information or not.
>
> To distinguish "EXPLAIN ANALYZE TIMING OFF" or not, I use
> queryDesc->instrument_options has INSTRUMENT_ROWS flag or not.
> And also to distinguish if auto_explain needs timing info or not,
> I use queryDesc->instrument_options has INSTRUMENT_TIMING flag or not.
>
> This works fine, but I'm not sure I should to use INSTRUMENT_ROWS flag
> for this. Because it seems that the flags is used but not referenced
> from anywhere in current code.
> Will this flag be obsoleted?
>
>
> regards,
> --------------------
> Tomonari Katsumata
>
>