aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-09-22 11:29:18 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2011-09-22 11:30:11 -0400
commitf1972723654947f70409716757aa83f3d93c8fab (patch)
treed4f63965f021b29c30702df069941fb340074dcc /src/backend/executor
parent4893552e21b93149bb60f6204673cce855881a05 (diff)
downloadpostgresql-f1972723654947f70409716757aa83f3d93c8fab.tar.gz
postgresql-f1972723654947f70409716757aa83f3d93c8fab.zip
Make EXPLAIN ANALYZE report the numbers of rows rejected by filter steps.
This provides information about the numbers of tuples that were visited but not returned by table scans, as well as the numbers of join tuples that were considered and discarded within a join plan node. There is still some discussion going on about the best way to report counts for outer-join situations, but I think most of what's in the patch would not change if we revise that, so I'm going to go ahead and commit it as-is. Documentation changes to follow (they weren't in the submitted patch either). Marko Tiikkaja, reviewed by Marc Cousin, somewhat revised by Tom
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execAmi.c1
-rw-r--r--src/backend/executor/execMain.c1
-rw-r--r--src/backend/executor/execProcnode.c1
-rw-r--r--src/backend/executor/execScan.c2
-rw-r--r--src/backend/executor/instrument.c14
-rw-r--r--src/backend/executor/nodeAgg.c4
-rw-r--r--src/backend/executor/nodeBitmapAnd.c1
-rw-r--r--src/backend/executor/nodeBitmapHeapscan.c1
-rw-r--r--src/backend/executor/nodeBitmapIndexscan.c1
-rw-r--r--src/backend/executor/nodeBitmapOr.c1
-rw-r--r--src/backend/executor/nodeGroup.c4
-rw-r--r--src/backend/executor/nodeHash.c1
-rw-r--r--src/backend/executor/nodeHashjoin.c8
-rw-r--r--src/backend/executor/nodeIndexscan.c6
-rw-r--r--src/backend/executor/nodeMergejoin.c8
-rw-r--r--src/backend/executor/nodeNestloop.c6
16 files changed, 46 insertions, 14 deletions
diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c
index ffdcc966ee6..711e8c77866 100644
--- a/src/backend/executor/execAmi.c
+++ b/src/backend/executor/execAmi.c
@@ -13,7 +13,6 @@
#include "postgres.h"
#include "executor/execdebug.h"
-#include "executor/instrument.h"
#include "executor/nodeAgg.h"
#include "executor/nodeAppend.h"
#include "executor/nodeBitmapAnd.h"
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index 1dfe8b9ac78..fd7a9ed0339 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -47,7 +47,6 @@
#include "commands/tablespace.h"
#include "commands/trigger.h"
#include "executor/execdebug.h"
-#include "executor/instrument.h"
#include "miscadmin.h"
#include "optimizer/clauses.h"
#include "parser/parse_clause.h"
diff --git a/src/backend/executor/execProcnode.c b/src/backend/executor/execProcnode.c
index 17788761d7f..8bdfad22223 100644
--- a/src/backend/executor/execProcnode.c
+++ b/src/backend/executor/execProcnode.c
@@ -77,7 +77,6 @@
#include "postgres.h"
#include "executor/executor.h"
-#include "executor/instrument.h"
#include "executor/nodeAgg.h"
#include "executor/nodeAppend.h"
#include "executor/nodeBitmapAnd.h"
diff --git a/src/backend/executor/execScan.c b/src/backend/executor/execScan.c
index e90058847d9..d4ed2358564 100644
--- a/src/backend/executor/execScan.c
+++ b/src/backend/executor/execScan.c
@@ -219,6 +219,8 @@ ExecScan(ScanState *node,
return slot;
}
}
+ else
+ InstrCountFiltered1(node, 1);
/*
* Tuple fails qual, so free per-tuple memory and try again.
diff --git a/src/backend/executor/instrument.c b/src/backend/executor/instrument.c
index bf9bf12ab6a..9d30200ab3c 100644
--- a/src/backend/executor/instrument.c
+++ b/src/backend/executor/instrument.c
@@ -22,6 +22,7 @@ BufferUsage pgBufferUsage;
static void BufferUsageAccumDiff(BufferUsage *dst,
const BufferUsage *add, const BufferUsage *sub);
+
/* Allocate new instrumentation structure(s) */
Instrumentation *
InstrAlloc(int n, int instrument_options)
@@ -31,13 +32,14 @@ InstrAlloc(int n, int instrument_options)
/* timer is always required for now */
Assert(instrument_options & INSTRUMENT_TIMER);
+ /* initialize all fields to zeroes, then modify as needed */
instr = palloc0(n * sizeof(Instrumentation));
if (instrument_options & INSTRUMENT_BUFFERS)
{
int i;
for (i = 0; i < n; i++)
- instr[i].needs_bufusage = true;
+ instr[i].need_bufusage = true;
}
return instr;
@@ -52,8 +54,8 @@ InstrStartNode(Instrumentation *instr)
else
elog(DEBUG2, "InstrStartNode called twice in a row");
- /* initialize buffer usage per plan node */
- if (instr->needs_bufusage)
+ /* save buffer usage totals at node entry, if needed */
+ if (instr->need_bufusage)
instr->bufusage_start = pgBufferUsage;
}
@@ -77,8 +79,8 @@ InstrStopNode(Instrumentation *instr, double nTuples)
INSTR_TIME_SET_ZERO(instr->starttime);
- /* Adds delta of buffer usage to node's count. */
- if (instr->needs_bufusage)
+ /* Add delta of buffer usage since entry to node's totals */
+ if (instr->need_bufusage)
BufferUsageAccumDiff(&instr->bufusage,
&pgBufferUsage, &instr->bufusage_start);
@@ -119,12 +121,12 @@ InstrEndLoop(Instrumentation *instr)
instr->tuplecount = 0;
}
+/* dst += add - sub */
static void
BufferUsageAccumDiff(BufferUsage *dst,
const BufferUsage *add,
const BufferUsage *sub)
{
- /* dst += add - sub */
dst->shared_blks_hit += add->shared_blks_hit - sub->shared_blks_hit;
dst->shared_blks_read += add->shared_blks_read - sub->shared_blks_read;
dst->shared_blks_written += add->shared_blks_written - sub->shared_blks_written;
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 13d77234801..e769d6d012c 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -1204,6 +1204,8 @@ agg_retrieve_direct(AggState *aggstate)
return result;
}
}
+ else
+ InstrCountFiltered1(aggstate, 1);
}
/* No more groups */
@@ -1354,6 +1356,8 @@ agg_retrieve_hash_table(AggState *aggstate)
return result;
}
}
+ else
+ InstrCountFiltered1(aggstate, 1);
}
/* No more groups */
diff --git a/src/backend/executor/nodeBitmapAnd.c b/src/backend/executor/nodeBitmapAnd.c
index 82308cba260..5f318c31e77 100644
--- a/src/backend/executor/nodeBitmapAnd.c
+++ b/src/backend/executor/nodeBitmapAnd.c
@@ -29,7 +29,6 @@
#include "postgres.h"
#include "executor/execdebug.h"
-#include "executor/instrument.h"
#include "executor/nodeBitmapAnd.h"
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index 8e50fb1aaef..4a8920e6ce8 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -278,6 +278,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
if (!ExecQual(node->bitmapqualorig, econtext, false))
{
/* Fails recheck, so drop it and loop back for another */
+ InstrCountFiltered2(node, 1);
ExecClearTuple(slot);
continue;
}
diff --git a/src/backend/executor/nodeBitmapIndexscan.c b/src/backend/executor/nodeBitmapIndexscan.c
index 9a56fd4b9fd..8e1df079b37 100644
--- a/src/backend/executor/nodeBitmapIndexscan.c
+++ b/src/backend/executor/nodeBitmapIndexscan.c
@@ -22,7 +22,6 @@
#include "postgres.h"
#include "executor/execdebug.h"
-#include "executor/instrument.h"
#include "executor/nodeBitmapIndexscan.h"
#include "executor/nodeIndexscan.h"
#include "miscadmin.h"
diff --git a/src/backend/executor/nodeBitmapOr.c b/src/backend/executor/nodeBitmapOr.c
index 4b064b79a96..d2453d5a4f0 100644
--- a/src/backend/executor/nodeBitmapOr.c
+++ b/src/backend/executor/nodeBitmapOr.c
@@ -29,7 +29,6 @@
#include "postgres.h"
#include "executor/execdebug.h"
-#include "executor/instrument.h"
#include "executor/nodeBitmapOr.h"
#include "miscadmin.h"
diff --git a/src/backend/executor/nodeGroup.c b/src/backend/executor/nodeGroup.c
index fa403e5406c..7bef8bbe8b9 100644
--- a/src/backend/executor/nodeGroup.c
+++ b/src/backend/executor/nodeGroup.c
@@ -118,6 +118,8 @@ ExecGroup(GroupState *node)
return result;
}
}
+ else
+ InstrCountFiltered1(node, 1);
}
/*
@@ -179,6 +181,8 @@ ExecGroup(GroupState *node)
return result;
}
}
+ else
+ InstrCountFiltered1(node, 1);
}
/* NOTREACHED */
diff --git a/src/backend/executor/nodeHash.c b/src/backend/executor/nodeHash.c
index 2ade2d7fad6..e72a71bf51b 100644
--- a/src/backend/executor/nodeHash.c
+++ b/src/backend/executor/nodeHash.c
@@ -28,7 +28,6 @@
#include "commands/tablespace.h"
#include "executor/execdebug.h"
#include "executor/hashjoin.h"
-#include "executor/instrument.h"
#include "executor/nodeHash.h"
#include "executor/nodeHashjoin.h"
#include "miscadmin.h"
diff --git a/src/backend/executor/nodeHashjoin.c b/src/backend/executor/nodeHashjoin.c
index 3a6698105f2..c3c4db4bc2c 100644
--- a/src/backend/executor/nodeHashjoin.c
+++ b/src/backend/executor/nodeHashjoin.c
@@ -325,7 +325,11 @@ ExecHashJoin(HashJoinState *node)
return result;
}
}
+ else
+ InstrCountFiltered2(node, 1);
}
+ else
+ InstrCountFiltered1(node, 1);
break;
case HJ_FILL_OUTER_TUPLE:
@@ -360,6 +364,8 @@ ExecHashJoin(HashJoinState *node)
return result;
}
}
+ else
+ InstrCountFiltered2(node, 1);
}
break;
@@ -397,6 +403,8 @@ ExecHashJoin(HashJoinState *node)
return result;
}
}
+ else
+ InstrCountFiltered2(node, 1);
break;
case HJ_NEED_NEW_BATCH:
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index 955008e012d..da25384e860 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -96,7 +96,11 @@ IndexNext(IndexScanState *node)
econtext->ecxt_scantuple = slot;
ResetExprContext(econtext);
if (!ExecQual(node->indexqualorig, econtext, false))
- continue; /* nope, so ask index for another one */
+ {
+ /* Fails recheck, so drop it and loop back for another */
+ InstrCountFiltered2(node, 1);
+ continue;
+ }
}
return slot;
diff --git a/src/backend/executor/nodeMergejoin.c b/src/backend/executor/nodeMergejoin.c
index e23dd6c9f54..deaa79ed9fb 100644
--- a/src/backend/executor/nodeMergejoin.c
+++ b/src/backend/executor/nodeMergejoin.c
@@ -505,6 +505,8 @@ MJFillOuter(MergeJoinState *node)
return result;
}
}
+ else
+ InstrCountFiltered2(node, 1);
return NULL;
}
@@ -544,6 +546,8 @@ MJFillInner(MergeJoinState *node)
return result;
}
}
+ else
+ InstrCountFiltered2(node, 1);
return NULL;
}
@@ -893,7 +897,11 @@ ExecMergeJoin(MergeJoinState *node)
return result;
}
}
+ else
+ InstrCountFiltered2(node, 1);
}
+ else
+ InstrCountFiltered1(node, 1);
break;
/*
diff --git a/src/backend/executor/nodeNestloop.c b/src/backend/executor/nodeNestloop.c
index e98bc0f5a30..49b880d0caf 100644
--- a/src/backend/executor/nodeNestloop.c
+++ b/src/backend/executor/nodeNestloop.c
@@ -214,6 +214,8 @@ ExecNestLoop(NestLoopState *node)
return result;
}
}
+ else
+ InstrCountFiltered2(node, 1);
}
/*
@@ -270,7 +272,11 @@ ExecNestLoop(NestLoopState *node)
return result;
}
}
+ else
+ InstrCountFiltered2(node, 1);
}
+ else
+ InstrCountFiltered1(node, 1);
/*
* Tuple fails qual, so free per-tuple memory and try again.