Skip to content

Commit

Permalink
Optimize operator expression construction
Browse files Browse the repository at this point in the history
This commit aims to add a cache to avoid multiple calls to
GetDefaultOpClass. The call leads to s_lock to be called more than %70
with concurrent connections over 256. Caching is applied to
baseConstraint of partition columns on the tables.
  • Loading branch information
onderkalaci committed Jan 15, 2015
1 parent f1490b4 commit b90852b
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 2 deletions.
71 changes: 69 additions & 2 deletions prune_shard_list.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,15 @@
#include "utils/errcodes.h"
#include "utils/lsyscache.h"
#include "utils/typcache.h"
#include "utils/memutils.h"


/*
* BaseConstraintCache is used for caching base constraints for partition
* columns of distributed tables. It is initialized to empty list as
* there are no items in the cache.
*/
static List *BaseConstraintCache = NIL;


/* local function forward declarations */
Expand All @@ -51,6 +60,7 @@ static Const * MakeInt4Constant(Datum constantValue);
static OpExpr * MakeHashedOperatorExpression(OpExpr *operatorExpression);
static OpExpr * MakeOpExpressionWithZeroConst(void);
static List * BuildRestrictInfoList(List *qualList);
static Node * LookupBaseConstraint(Var *column);
static Node * BuildBaseConstraint(Var *column);
static void UpdateConstraint(Node *baseConstraint, ShardInterval *shardInterval);

Expand Down Expand Up @@ -90,8 +100,8 @@ PruneShardList(Oid relationId, List *whereClauseList, List *shardIntervalList)
partitionColumn = MakeInt4Column();
}

/* build the base expression for constraint */
baseConstraint = BuildBaseConstraint(partitionColumn);
/* lookup the base expression for constraint */
baseConstraint = LookupBaseConstraint(partitionColumn);

/* walk over shard list and check if shards can be pruned */
foreach(shardIntervalCell, shardIntervalList)
Expand Down Expand Up @@ -144,6 +154,63 @@ BuildRestrictInfoList(List *qualList)
}


/*
* LookupBaseConstraint is wrapper around BuildBaseConstraint that uses a
* cache to avoid multiple times to create the base constraint within a single
* session. This function never returns NULL.
*/
static Node *
LookupBaseConstraint(Var *partitionColumn)
{
Oid partitionColumnVarType = partitionColumn->vartype;
BaseConstraintCacheEntry *matchingCacheEntry = NULL;
ListCell *cacheEntryCell = NULL;

/* search the cache */
foreach(cacheEntryCell, BaseConstraintCache)
{
BaseConstraintCacheEntry *cacheEntry = lfirst(cacheEntryCell);
if (cacheEntry->columnVarType == partitionColumnVarType)
{
matchingCacheEntry = cacheEntry;
break;
}
}

/* if not found in the cache, build the base constraint and put it in cache */
if (matchingCacheEntry == NULL)
{
Node *builtBaseConstraint = NULL;
MemoryContext oldContext = MemoryContextSwitchTo(CacheMemoryContext);

/*
* Explicitly create partition column variable in CacheMemoryContext. It is
* critical because partitionColumn variable is created in MessageContext
* and will be freed when MessageContext is reseted. However, we need partition
* column variable in a longer context, which is CacheMemoryContext.
*/
Var *partitionColumnInCacheMemory = makeVar(partitionColumn->varno,
partitionColumn->varattno,
partitionColumn->vartype,
partitionColumn->vartypmod,
partitionColumn->varcollid,
partitionColumn->varlevelsup);

builtBaseConstraint = BuildBaseConstraint(partitionColumnInCacheMemory);

matchingCacheEntry = palloc0(sizeof(BaseConstraintCacheEntry));
matchingCacheEntry->columnVarType = partitionColumnVarType;
matchingCacheEntry->baseConstraint = builtBaseConstraint;

BaseConstraintCache = lappend(BaseConstraintCache, matchingCacheEntry);

MemoryContextSwitchTo(oldContext);
}

return matchingCacheEntry->baseConstraint;
}


/*
* BuildBaseConstraint builds and returns a base constraint. This constraint
* implements an expression in the form of (column <= max && column >= min),
Expand Down
11 changes: 11 additions & 0 deletions prune_shard_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@
#define RESERVED_HASHED_COLUMN_ID MaxAttrNumber


/*
* BaseConstraintCacheEntry contains the information for a cache entry in
* base constraint cache.
*/
typedef struct BaseConstraintCacheEntry
{
Oid columnVarType; /* cache key */
Node *baseConstraint;
} BaseConstraintCacheEntry;


/* function declarations for shard pruning */
extern List * PruneShardList(Oid relationId, List *whereClauseList,
List *shardIntervalList);
Expand Down

0 comments on commit b90852b

Please sign in to comment.