1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-15 19:21:59 +03:00

Fix performance problems with pg_index lookups (see, for example,

discussion of 5/19/00).  pg_index is now searched for indexes of a
relation using an indexscan.  Moreover, this is done once and cached
in the relcache entry for the relation, in the form of a list of OIDs
for the indexes.  This list is used by the parser and executor to drive
lookups in the pg_index syscache when they want to know the properties
of the indexes.  Net result: index information will be fully cached
for repetitive operations such as inserts.
This commit is contained in:
Tom Lane
2000-06-17 21:49:04 +00:00
parent 9cf80f2f55
commit d03a933ec5
13 changed files with 389 additions and 525 deletions

View File

@ -9,11 +9,7 @@
*
*
* IDENTIFICATION
<<<<<<< plancat.c
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.56 2000/06/15 03:32:16 momjian Exp $
=======
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.56 2000/06/15 03:32:16 momjian Exp $
>>>>>>> 1.53
* $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.57 2000/06/17 21:48:51 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -32,6 +28,7 @@
#include "parser/parsetree.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/relcache.h"
#include "utils/syscache.h"
#include "catalog/catalog.h"
#include "miscadmin.h"
@ -54,7 +51,7 @@ relation_info(Query *root, Index relid,
Form_pg_class relation;
relationTuple = SearchSysCacheTuple(RELOID,
ObjectIdGetDatum(relationObjectId),
ObjectIdGetDatum(relationObjectId),
0, 0, 0);
if (!HeapTupleIsValid(relationTuple))
elog(ERROR, "relation_info: Relation %u not found",
@ -81,33 +78,40 @@ relation_info(Query *root, Index relid,
List *
find_secondary_indexes(Query *root, Index relid)
{
List *indexes = NIL;
List *indexinfos = NIL;
List *indexoidlist,
*indexoidscan;
Oid indrelid = getrelid(relid, root->rtable);
Relation relation;
HeapScanDesc scan;
ScanKeyData indexKey;
HeapTuple indexTuple;
/* Scan pg_index for tuples describing indexes of this rel */
relation = heap_openr(IndexRelationName, AccessShareLock);
/*
* We used to scan pg_index directly, but now the relcache offers
* a cached list of OID indexes for each relation. So, get that list
* and then use the syscache to obtain pg_index entries.
*/
relation = heap_open(indrelid, AccessShareLock);
indexoidlist = RelationGetIndexList(relation);
ScanKeyEntryInitialize(&indexKey, 0,
Anum_pg_index_indrelid,
F_OIDEQ,
ObjectIdGetDatum(indrelid));
scan = heap_beginscan(relation, 0, SnapshotNow,
1, &indexKey);
while (HeapTupleIsValid(indexTuple = heap_getnext(scan, 0)))
foreach(indexoidscan, indexoidlist)
{
Form_pg_index index = (Form_pg_index) GETSTRUCT(indexTuple);
IndexOptInfo *info = makeNode(IndexOptInfo);
Oid indexoid = lfirsti(indexoidscan);
HeapTuple indexTuple;
Form_pg_index index;
IndexOptInfo *info;
int i;
Relation indexRelation;
Oid relam;
uint16 amorderstrategy;
indexTuple = SearchSysCacheTupleCopy(INDEXRELID,
ObjectIdGetDatum(indexoid),
0, 0, 0);
if (!HeapTupleIsValid(indexTuple))
elog(ERROR, "find_secondary_indexes: index %u not found",
indexoid);
index = (Form_pg_index) GETSTRUCT(indexTuple);
info = makeNode(IndexOptInfo);
/*
* Need to make these arrays large enough to be sure there is a
* terminating 0 at the end of each one.
@ -172,13 +176,17 @@ find_secondary_indexes(Query *root, Index relid)
}
}
indexes = lcons(info, indexes);
heap_freetuple(indexTuple);
indexinfos = lcons(info, indexinfos);
}
heap_endscan(scan);
freeList(indexoidlist);
/* XXX keep the lock here? */
heap_close(relation, AccessShareLock);
return indexes;
return indexinfos;
}
/*