
Here we add ExprState support for obtaining a 32-bit hash value from a list of expressions. This allows both faster hashing and also JIT compilation of these expressions. This is especially useful when hash joins have multiple join keys as the previous code called ExecEvalExpr on each hash join key individually and that was inefficient as tuple deformation would have only taken into account one key at a time, which could lead to walking the tuple once for each join key. With the new code, we'll determine the maximum attribute required and deform the tuple to that point only once. Some performance tests done with this change have shown up to a 20% performance increase of a query containing a Hash Join without JIT compilation and up to a 26% performance increase when JIT is enabled and optimization and inlining were performed by the JIT compiler. The performance increase with 1 join column was less with a 14% increase with and without JIT. This test was done using a fairly small hash table and a large number of hash probes. The increase will likely be less with large tables, especially ones larger than L3 cache as memory pressure is more likely to be the limiting factor there. This commit only addresses Hash Joins, but lays expression evaluation and JIT compilation infrastructure for other hashing needs such as Hash Aggregate. Author: David Rowley Reviewed-by: Alexey Dvoichenkov <alexey@hyperplane.net> Reviewed-by: Tels <nospam-pg-abuse@bloodgate.com> Discussion: https://postgr.es/m/CAApHDvoexAxgQFNQD_GRkr2O_eJUD1-wUGm%3Dm0L%2BGc%3DT%3DkEa4g%40mail.gmail.com
76 lines
3.1 KiB
C
76 lines
3.1 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* nodeHash.h
|
|
* prototypes for nodeHash.c
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/executor/nodeHash.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef NODEHASH_H
|
|
#define NODEHASH_H
|
|
|
|
#include "access/parallel.h"
|
|
#include "nodes/execnodes.h"
|
|
|
|
struct SharedHashJoinBatch;
|
|
|
|
extern HashState *ExecInitHash(Hash *node, EState *estate, int eflags);
|
|
extern Node *MultiExecHash(HashState *node);
|
|
extern void ExecEndHash(HashState *node);
|
|
extern void ExecReScanHash(HashState *node);
|
|
|
|
extern HashJoinTable ExecHashTableCreate(HashState *state);
|
|
extern void ExecParallelHashTableAlloc(HashJoinTable hashtable,
|
|
int batchno);
|
|
extern void ExecHashTableDestroy(HashJoinTable hashtable);
|
|
extern void ExecHashTableDetach(HashJoinTable hashtable);
|
|
extern void ExecHashTableDetachBatch(HashJoinTable hashtable);
|
|
extern void ExecParallelHashTableSetCurrentBatch(HashJoinTable hashtable,
|
|
int batchno);
|
|
|
|
extern void ExecHashTableInsert(HashJoinTable hashtable,
|
|
TupleTableSlot *slot,
|
|
uint32 hashvalue);
|
|
extern void ExecParallelHashTableInsert(HashJoinTable hashtable,
|
|
TupleTableSlot *slot,
|
|
uint32 hashvalue);
|
|
extern void ExecParallelHashTableInsertCurrentBatch(HashJoinTable hashtable,
|
|
TupleTableSlot *slot,
|
|
uint32 hashvalue);
|
|
extern void ExecHashGetBucketAndBatch(HashJoinTable hashtable,
|
|
uint32 hashvalue,
|
|
int *bucketno,
|
|
int *batchno);
|
|
extern bool ExecScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
|
|
extern bool ExecParallelScanHashBucket(HashJoinState *hjstate, ExprContext *econtext);
|
|
extern void ExecPrepHashTableForUnmatched(HashJoinState *hjstate);
|
|
extern bool ExecParallelPrepHashTableForUnmatched(HashJoinState *hjstate);
|
|
extern bool ExecScanHashTableForUnmatched(HashJoinState *hjstate,
|
|
ExprContext *econtext);
|
|
extern bool ExecParallelScanHashTableForUnmatched(HashJoinState *hjstate,
|
|
ExprContext *econtext);
|
|
extern void ExecHashTableReset(HashJoinTable hashtable);
|
|
extern void ExecHashTableResetMatchFlags(HashJoinTable hashtable);
|
|
extern void ExecChooseHashTableSize(double ntuples, int tupwidth, bool useskew,
|
|
bool try_combined_hash_mem,
|
|
int parallel_workers,
|
|
size_t *space_allowed,
|
|
int *numbuckets,
|
|
int *numbatches,
|
|
int *num_skew_mcvs);
|
|
extern int ExecHashGetSkewBucket(HashJoinTable hashtable, uint32 hashvalue);
|
|
extern void ExecHashEstimate(HashState *node, ParallelContext *pcxt);
|
|
extern void ExecHashInitializeDSM(HashState *node, ParallelContext *pcxt);
|
|
extern void ExecHashInitializeWorker(HashState *node, ParallelWorkerContext *pwcxt);
|
|
extern void ExecHashRetrieveInstrumentation(HashState *node);
|
|
extern void ExecShutdownHash(HashState *node);
|
|
extern void ExecHashAccumInstrumentation(HashInstrumentation *instrument,
|
|
HashJoinTable hashtable);
|
|
|
|
#endif /* NODEHASH_H */
|