mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-27 08:39:28 +08:00
Augment EXPLAIN output with more details on Hash nodes.
We show the number of buckets, the number of batches (and also the original number if it has changed), and the peak space used by the hash table. Minor executor changes to track peak space used.
This commit is contained in:
parent
cccfc4efc4
commit
42a8ab0a14
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1994-5, Regents of the University of California
|
* Portions Copyright (c) 1994-5, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.199 2010/01/15 22:36:29 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/commands/explain.c,v 1.200 2010/02/01 15:43:35 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -20,6 +20,7 @@
|
|||||||
#include "commands/explain.h"
|
#include "commands/explain.h"
|
||||||
#include "commands/prepare.h"
|
#include "commands/prepare.h"
|
||||||
#include "commands/trigger.h"
|
#include "commands/trigger.h"
|
||||||
|
#include "executor/hashjoin.h"
|
||||||
#include "executor/instrument.h"
|
#include "executor/instrument.h"
|
||||||
#include "optimizer/clauses.h"
|
#include "optimizer/clauses.h"
|
||||||
#include "optimizer/planner.h"
|
#include "optimizer/planner.h"
|
||||||
@ -67,6 +68,7 @@ static void show_upper_qual(List *qual, const char *qlabel, Plan *plan,
|
|||||||
ExplainState *es);
|
ExplainState *es);
|
||||||
static void show_sort_keys(Plan *sortplan, ExplainState *es);
|
static void show_sort_keys(Plan *sortplan, ExplainState *es);
|
||||||
static void show_sort_info(SortState *sortstate, ExplainState *es);
|
static void show_sort_info(SortState *sortstate, ExplainState *es);
|
||||||
|
static void show_hash_info(HashState *hashstate, ExplainState *es);
|
||||||
static const char *explain_get_index_name(Oid indexId);
|
static const char *explain_get_index_name(Oid indexId);
|
||||||
static void ExplainScanTarget(Scan *plan, ExplainState *es);
|
static void ExplainScanTarget(Scan *plan, ExplainState *es);
|
||||||
static void ExplainMemberNodes(List *plans, PlanState **planstate,
|
static void ExplainMemberNodes(List *plans, PlanState **planstate,
|
||||||
@ -1052,6 +1054,9 @@ ExplainNode(Plan *plan, PlanState *planstate,
|
|||||||
"One-Time Filter", plan, es);
|
"One-Time Filter", plan, es);
|
||||||
show_upper_qual(plan->qual, "Filter", plan, es);
|
show_upper_qual(plan->qual, "Filter", plan, es);
|
||||||
break;
|
break;
|
||||||
|
case T_Hash:
|
||||||
|
show_hash_info((HashState *) planstate, es);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1404,6 +1409,47 @@ show_sort_info(SortState *sortstate, ExplainState *es)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show information on hash buckets/batches.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
show_hash_info(HashState *hashstate, ExplainState *es)
|
||||||
|
{
|
||||||
|
HashJoinTable hashtable;
|
||||||
|
|
||||||
|
Assert(IsA(hashstate, HashState));
|
||||||
|
hashtable = hashstate->hashtable;
|
||||||
|
|
||||||
|
if (hashtable)
|
||||||
|
{
|
||||||
|
long spacePeakKb = (hashtable->spacePeak + 1023) / 1024;
|
||||||
|
if (es->format != EXPLAIN_FORMAT_TEXT)
|
||||||
|
{
|
||||||
|
ExplainPropertyLong("Hash Buckets", hashtable->nbuckets, es);
|
||||||
|
ExplainPropertyLong("Hash Batches", hashtable->nbatch, es);
|
||||||
|
ExplainPropertyLong("Original Hash Batches",
|
||||||
|
hashtable->nbatch_original, es);
|
||||||
|
ExplainPropertyLong("Peak Memory Usage", spacePeakKb, es);
|
||||||
|
}
|
||||||
|
else if (hashtable->nbatch_original != hashtable->nbatch)
|
||||||
|
{
|
||||||
|
appendStringInfoSpaces(es->str, es->indent * 2);
|
||||||
|
appendStringInfo(es->str,
|
||||||
|
"Buckets: %d Batches: %d (originally %d) Memory Usage: %ldkB\n",
|
||||||
|
hashtable->nbuckets, hashtable->nbatch,
|
||||||
|
hashtable->nbatch_original, spacePeakKb);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
appendStringInfoSpaces(es->str, es->indent * 2);
|
||||||
|
appendStringInfo(es->str,
|
||||||
|
"Buckets: %d Batches: %d Memory Usage: %ldkB\n",
|
||||||
|
hashtable->nbuckets, hashtable->nbatch,
|
||||||
|
spacePeakKb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fetch the name of an index in an EXPLAIN
|
* Fetch the name of an index in an EXPLAIN
|
||||||
*
|
*
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.126 2010/01/04 02:44:39 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/nodeHash.c,v 1.127 2010/02/01 15:43:36 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -287,6 +287,7 @@ ExecHashTableCreate(Hash *node, List *hashOperators)
|
|||||||
hashtable->innerBatchFile = NULL;
|
hashtable->innerBatchFile = NULL;
|
||||||
hashtable->outerBatchFile = NULL;
|
hashtable->outerBatchFile = NULL;
|
||||||
hashtable->spaceUsed = 0;
|
hashtable->spaceUsed = 0;
|
||||||
|
hashtable->spacePeak = 0;
|
||||||
hashtable->spaceAllowed = work_mem * 1024L;
|
hashtable->spaceAllowed = work_mem * 1024L;
|
||||||
hashtable->spaceUsedSkew = 0;
|
hashtable->spaceUsedSkew = 0;
|
||||||
hashtable->spaceAllowedSkew =
|
hashtable->spaceAllowedSkew =
|
||||||
@ -719,6 +720,8 @@ ExecHashTableInsert(HashJoinTable hashtable,
|
|||||||
hashTuple->next = hashtable->buckets[bucketno];
|
hashTuple->next = hashtable->buckets[bucketno];
|
||||||
hashtable->buckets[bucketno] = hashTuple;
|
hashtable->buckets[bucketno] = hashTuple;
|
||||||
hashtable->spaceUsed += hashTupleSize;
|
hashtable->spaceUsed += hashTupleSize;
|
||||||
|
if (hashtable->spaceUsed > hashtable->spacePeak)
|
||||||
|
hashtable->spacePeak = hashtable->spaceUsed;
|
||||||
if (hashtable->spaceUsed > hashtable->spaceAllowed)
|
if (hashtable->spaceUsed > hashtable->spaceAllowed)
|
||||||
ExecHashIncreaseNumBatches(hashtable);
|
ExecHashIncreaseNumBatches(hashtable);
|
||||||
}
|
}
|
||||||
@ -1071,6 +1074,8 @@ ExecHashBuildSkewHash(HashJoinTable hashtable, Hash *node, int mcvsToUse)
|
|||||||
+ mcvsToUse * sizeof(int);
|
+ mcvsToUse * sizeof(int);
|
||||||
hashtable->spaceUsedSkew += nbuckets * sizeof(HashSkewBucket *)
|
hashtable->spaceUsedSkew += nbuckets * sizeof(HashSkewBucket *)
|
||||||
+ mcvsToUse * sizeof(int);
|
+ mcvsToUse * sizeof(int);
|
||||||
|
if (hashtable->spaceUsed > hashtable->spacePeak)
|
||||||
|
hashtable->spacePeak = hashtable->spaceUsed;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create a skew bucket for each MCV hash value.
|
* Create a skew bucket for each MCV hash value.
|
||||||
@ -1119,6 +1124,8 @@ ExecHashBuildSkewHash(HashJoinTable hashtable, Hash *node, int mcvsToUse)
|
|||||||
hashtable->nSkewBuckets++;
|
hashtable->nSkewBuckets++;
|
||||||
hashtable->spaceUsed += SKEW_BUCKET_OVERHEAD;
|
hashtable->spaceUsed += SKEW_BUCKET_OVERHEAD;
|
||||||
hashtable->spaceUsedSkew += SKEW_BUCKET_OVERHEAD;
|
hashtable->spaceUsedSkew += SKEW_BUCKET_OVERHEAD;
|
||||||
|
if (hashtable->spaceUsed > hashtable->spacePeak)
|
||||||
|
hashtable->spacePeak = hashtable->spaceUsed;
|
||||||
}
|
}
|
||||||
|
|
||||||
free_attstatsslot(node->skewColType,
|
free_attstatsslot(node->skewColType,
|
||||||
@ -1205,6 +1212,8 @@ ExecHashSkewTableInsert(HashJoinTable hashtable,
|
|||||||
/* Account for space used, and back off if we've used too much */
|
/* Account for space used, and back off if we've used too much */
|
||||||
hashtable->spaceUsed += hashTupleSize;
|
hashtable->spaceUsed += hashTupleSize;
|
||||||
hashtable->spaceUsedSkew += hashTupleSize;
|
hashtable->spaceUsedSkew += hashTupleSize;
|
||||||
|
if (hashtable->spaceUsed > hashtable->spacePeak)
|
||||||
|
hashtable->spacePeak = hashtable->spaceUsed;
|
||||||
while (hashtable->spaceUsedSkew > hashtable->spaceAllowedSkew)
|
while (hashtable->spaceUsedSkew > hashtable->spaceAllowedSkew)
|
||||||
ExecHashRemoveNextSkewBucket(hashtable);
|
ExecHashRemoveNextSkewBucket(hashtable);
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/executor/hashjoin.h,v 1.52 2010/01/02 16:58:03 momjian Exp $
|
* $PostgreSQL: pgsql/src/include/executor/hashjoin.h,v 1.53 2010/02/01 15:43:36 rhaas Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -149,6 +149,7 @@ typedef struct HashJoinTableData
|
|||||||
|
|
||||||
Size spaceUsed; /* memory space currently used by tuples */
|
Size spaceUsed; /* memory space currently used by tuples */
|
||||||
Size spaceAllowed; /* upper limit for space used */
|
Size spaceAllowed; /* upper limit for space used */
|
||||||
|
Size spacePeak; /* peak space used */
|
||||||
Size spaceUsedSkew; /* skew hash table's current space usage */
|
Size spaceUsedSkew; /* skew hash table's current space usage */
|
||||||
Size spaceAllowedSkew; /* upper limit for skew hashtable */
|
Size spaceAllowedSkew; /* upper limit for skew hashtable */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user