mirror of
https://github.com/postgres/postgres.git
synced 2026-05-16 11:29:49 -04:00
It's always been possible for index AMs to cache data across successive amgettuple calls within a single SQL command: the IndexScanDesc.opaque field is meant for precisely that. However, no comparable facility exists for amortizing setup work across successive aminsert calls. This patch adds such a feature and teaches GIN, GIST, and BRIN to use it to amortize catalog lookups they'd previously been doing on every call. (The other standard index AMs keep everything they need in the relcache, so there's little to improve there.) For GIN, the overall improvement in a statement that inserts many rows can be as much as 10%, though it seems a bit less for the other two. In addition, this makes a really significant difference in runtime for CLOBBER_CACHE_ALWAYS tests, since in those builds the repeated catalog lookups are vastly more expensive. The reason this has been hard up to now is that the aminsert function is not passed any useful place to cache per-statement data. What I chose to do is to add suitable fields to struct IndexInfo and pass that to aminsert. That's not widening the index AM API very much because IndexInfo is already within the ken of ambuild; in fact, by passing the same info to aminsert as to ambuild, this is really removing an inconsistency in the AM API. Discussion: https://postgr.es/m/27568.1486508680@sss.pgh.pa.us
110 lines
3.3 KiB
C
110 lines
3.3 KiB
C
/*
|
|
* brin_internal.h
|
|
* internal declarations for BRIN indexes
|
|
*
|
|
* Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* IDENTIFICATION
|
|
* src/include/access/brin_internal.h
|
|
*/
|
|
#ifndef BRIN_INTERNAL_H
|
|
#define BRIN_INTERNAL_H
|
|
|
|
#include "access/amapi.h"
|
|
#include "storage/bufpage.h"
|
|
#include "utils/typcache.h"
|
|
|
|
|
|
/*
|
|
* A BrinDesc is a struct designed to enable decoding a BRIN tuple from the
|
|
* on-disk format to an in-memory tuple and vice-versa.
|
|
*/
|
|
|
|
/* struct returned by "OpcInfo" amproc */
|
|
typedef struct BrinOpcInfo
|
|
{
|
|
/* Number of columns stored in an index column of this opclass */
|
|
uint16 oi_nstored;
|
|
|
|
/* Opaque pointer for the opclass' private use */
|
|
void *oi_opaque;
|
|
|
|
/* Type cache entries of the stored columns */
|
|
TypeCacheEntry *oi_typcache[FLEXIBLE_ARRAY_MEMBER];
|
|
} BrinOpcInfo;
|
|
|
|
/* the size of a BrinOpcInfo for the given number of columns */
|
|
#define SizeofBrinOpcInfo(ncols) \
|
|
(offsetof(BrinOpcInfo, oi_typcache) + sizeof(TypeCacheEntry *) * ncols)
|
|
|
|
typedef struct BrinDesc
|
|
{
|
|
/* Containing memory context */
|
|
MemoryContext bd_context;
|
|
|
|
/* the index relation itself */
|
|
Relation bd_index;
|
|
|
|
/* tuple descriptor of the index relation */
|
|
TupleDesc bd_tupdesc;
|
|
|
|
/* cached copy for on-disk tuples; generated at first use */
|
|
TupleDesc bd_disktdesc;
|
|
|
|
/* total number of Datum entries that are stored on-disk for all columns */
|
|
int bd_totalstored;
|
|
|
|
/* per-column info; bd_tupdesc->natts entries long */
|
|
BrinOpcInfo *bd_info[FLEXIBLE_ARRAY_MEMBER];
|
|
} BrinDesc;
|
|
|
|
/*
|
|
* Globally-known function support numbers for BRIN indexes. Individual
|
|
* opclasses can define more function support numbers, which must fall into
|
|
* BRIN_FIRST_OPTIONAL_PROCNUM .. BRIN_LAST_OPTIONAL_PROCNUM.
|
|
*/
|
|
#define BRIN_PROCNUM_OPCINFO 1
|
|
#define BRIN_PROCNUM_ADDVALUE 2
|
|
#define BRIN_PROCNUM_CONSISTENT 3
|
|
#define BRIN_PROCNUM_UNION 4
|
|
#define BRIN_MANDATORY_NPROCS 4
|
|
/* procedure numbers up to 10 are reserved for BRIN future expansion */
|
|
#define BRIN_FIRST_OPTIONAL_PROCNUM 11
|
|
#define BRIN_LAST_OPTIONAL_PROCNUM 15
|
|
|
|
#undef BRIN_DEBUG
|
|
|
|
#ifdef BRIN_DEBUG
|
|
#define BRIN_elog(args) elog args
|
|
#else
|
|
#define BRIN_elog(args) ((void) 0)
|
|
#endif
|
|
|
|
/* brin.c */
|
|
extern BrinDesc *brin_build_desc(Relation rel);
|
|
extern void brin_free_desc(BrinDesc *bdesc);
|
|
extern IndexBuildResult *brinbuild(Relation heap, Relation index,
|
|
struct IndexInfo *indexInfo);
|
|
extern void brinbuildempty(Relation index);
|
|
extern bool brininsert(Relation idxRel, Datum *values, bool *nulls,
|
|
ItemPointer heaptid, Relation heapRel,
|
|
IndexUniqueCheck checkUnique,
|
|
struct IndexInfo *indexInfo);
|
|
extern IndexScanDesc brinbeginscan(Relation r, int nkeys, int norderbys);
|
|
extern int64 bringetbitmap(IndexScanDesc scan, TIDBitmap *tbm);
|
|
extern void brinrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
|
|
ScanKey orderbys, int norderbys);
|
|
extern void brinendscan(IndexScanDesc scan);
|
|
extern IndexBulkDeleteResult *brinbulkdelete(IndexVacuumInfo *info,
|
|
IndexBulkDeleteResult *stats,
|
|
IndexBulkDeleteCallback callback,
|
|
void *callback_state);
|
|
extern IndexBulkDeleteResult *brinvacuumcleanup(IndexVacuumInfo *info,
|
|
IndexBulkDeleteResult *stats);
|
|
extern bytea *brinoptions(Datum reloptions, bool validate);
|
|
|
|
/* brin_validate.c */
|
|
extern bool brinvalidate(Oid opclassoid);
|
|
|
|
#endif /* BRIN_INTERNAL_H */
|