mirror of
https://github.com/postgres/postgres.git
synced 2025-04-24 10:47:04 +03:00
Delay build of Memoize hash table until executor run
Previously this hash table was built during executor startup. This could cause long delays in EXPLAIN (without ANALYZE) when the planner opts to use a large Memoize hash table. No backpatch for now due to lack of complaints. Author: David Rowley Discussion: https://postgr.es/m/CAApHDvoJktJ5XL=Kjh2a2TFr64R-7eQZV-+jcJrUwoES2GLiWg@mail.gmail.com
This commit is contained in:
parent
c85977d8fe
commit
57f59396bb
@ -278,11 +278,14 @@ MemoizeHash_equal(struct memoize_hash *tb, const MemoizeKey *key1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize the hash table to empty.
|
* Initialize the hash table to empty. The MemoizeState's hashtable field
|
||||||
|
* must point to NULL.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
build_hash_table(MemoizeState *mstate, uint32 size)
|
build_hash_table(MemoizeState *mstate, uint32 size)
|
||||||
{
|
{
|
||||||
|
Assert(mstate->hashtable == NULL);
|
||||||
|
|
||||||
/* Make a guess at a good size when we're not given a valid size. */
|
/* Make a guess at a good size when we're not given a valid size. */
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
size = 1024;
|
size = 1024;
|
||||||
@ -400,8 +403,10 @@ remove_cache_entry(MemoizeState *mstate, MemoizeEntry *entry)
|
|||||||
static void
|
static void
|
||||||
cache_purge_all(MemoizeState *mstate)
|
cache_purge_all(MemoizeState *mstate)
|
||||||
{
|
{
|
||||||
uint64 evictions = mstate->hashtable->members;
|
uint64 evictions = 0;
|
||||||
PlanState *pstate = (PlanState *) mstate;
|
|
||||||
|
if (mstate->hashtable != NULL)
|
||||||
|
evictions = mstate->hashtable->members;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Likely the most efficient way to remove all items is to just reset the
|
* Likely the most efficient way to remove all items is to just reset the
|
||||||
@ -410,8 +415,8 @@ cache_purge_all(MemoizeState *mstate)
|
|||||||
*/
|
*/
|
||||||
MemoryContextReset(mstate->tableContext);
|
MemoryContextReset(mstate->tableContext);
|
||||||
|
|
||||||
/* Make the hash table the same size as the original size */
|
/* NULLify so we recreate the table on the next call */
|
||||||
build_hash_table(mstate, ((Memoize *) pstate->plan)->est_entries);
|
mstate->hashtable = NULL;
|
||||||
|
|
||||||
/* reset the LRU list */
|
/* reset the LRU list */
|
||||||
dlist_init(&mstate->lru_list);
|
dlist_init(&mstate->lru_list);
|
||||||
@ -707,6 +712,10 @@ ExecMemoize(PlanState *pstate)
|
|||||||
|
|
||||||
Assert(node->entry == NULL);
|
Assert(node->entry == NULL);
|
||||||
|
|
||||||
|
/* first call? we'll need a hash table. */
|
||||||
|
if (unlikely(node->hashtable == NULL))
|
||||||
|
build_hash_table(node, ((Memoize *) pstate->plan)->est_entries);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We're only ever in this state for the first call of the
|
* We're only ever in this state for the first call of the
|
||||||
* scan. Here we have a look to see if we've already seen the
|
* scan. Here we have a look to see if we've already seen the
|
||||||
@ -1051,8 +1060,11 @@ ExecInitMemoize(Memoize *node, EState *estate, int eflags)
|
|||||||
/* Zero the statistics counters */
|
/* Zero the statistics counters */
|
||||||
memset(&mstate->stats, 0, sizeof(MemoizeInstrumentation));
|
memset(&mstate->stats, 0, sizeof(MemoizeInstrumentation));
|
||||||
|
|
||||||
/* Allocate and set up the actual cache */
|
/*
|
||||||
build_hash_table(mstate, node->est_entries);
|
* Because it may require a large allocation, we delay building of the
|
||||||
|
* hash table until executor run.
|
||||||
|
*/
|
||||||
|
mstate->hashtable = NULL;
|
||||||
|
|
||||||
return mstate;
|
return mstate;
|
||||||
}
|
}
|
||||||
@ -1062,6 +1074,7 @@ ExecEndMemoize(MemoizeState *node)
|
|||||||
{
|
{
|
||||||
#ifdef USE_ASSERT_CHECKING
|
#ifdef USE_ASSERT_CHECKING
|
||||||
/* Validate the memory accounting code is correct in assert builds. */
|
/* Validate the memory accounting code is correct in assert builds. */
|
||||||
|
if (node->hashtable != NULL)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
uint64 mem = 0;
|
uint64 mem = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user