60.4. Implementation
MulticolumnGIN indexes are implemented by building a single B-tree over composite values (column number, key value). The key values for different columns can be of different types.
Updating aGIN index tends to be slow because of the intrinsic nature of inverted indexes: inserting or updating one heap row can cause many inserts into the index (one for each key extracted from the indexed item). As ofPostgreSQL 8.4,GIN is capable of postponing much of this work by inserting new tuples into a temporary, unsorted list of pending entries. When the table is vacuumed or autoanalyzed, or whengin_clean_pending_list
function is called, or if the pending list becomes larger thangin_pending_list_limit, the entries are moved to the mainGIN data structure using the same bulk insert techniques used during initial index creation. This greatly improvesGIN index update speed, even counting the additional vacuum overhead. Moreover the overhead work can be done by a background process instead of in foreground query processing.
If consistent response time is more important than update speed, use of pending entries can be disabled by turning off thefastupdate
storage parameter for aGIN index. SeeCREATE INDEX for details.
60.4.2. Partial Match Algorithm
GIN can support“partial match” queries, in which the query does not determine an exact match for one or more keys, but the possible matches fall within a reasonably narrow range of key values (within the key sorting order determined by thecompare
support method). TheextractQuery
method, instead of returning a key value to be matched exactly, returns a key value that is the lower bound of the range to be searched, and sets thepmatch
flag true. The key range is then scanned using thecomparePartial
method.comparePartial
must return zero for a matching index key, less than zero for a non-match that is still within the range to be searched, or greater than zero if the index key is past the range that could match.