<acronym>GIN</acronym> stands for Generalized Inverted Index. <acronym>GIN</acronym> is designed for handling cases where the items to be indexed are composite values, and the queries to be handled by the index need to search for element values that appear within the composite items. For example, the items could be documents, and the queries could be searches for documents containing specific words. GINとは汎用転置インデックス(Generalized Inverted Index)を表します。 GINは、以下のような状況を取り扱うために設計されました。(1)インデックス対象の項目が複合型である。(2)そのインデックスにより処理される問い合わせは、複合型の項目内に存在する要素の値を検索する必要がある。 例えば、項目は文書であり、問い合わせは特定の単語を含む文書の検索です。
We use the word <firstterm>item</firstterm> to refer to a composite value that is to be indexed, and the word <firstterm>key</firstterm> to refer to an element value. <acronym>GIN</acronym> always stores and searches for keys, not item values per se. ここでは、インデックス対象の複合型の値を項目と呼びます。また、要素値をキーと呼びます。 GINは項目の値自体ではなく、常にキーを格納し検索します。
A <acronym>GIN</acronym> index stores a set of (key, posting list) pairs, where a <firstterm>posting list</firstterm> is a set of row IDs in which the key occurs. The same row ID can appear in multiple posting lists, since an item can contain more than one key. Each key value is stored only once, so a <acronym>GIN</acronym> index is very compact for cases where the same key appears many times. GINインデックスは(キー、ポスティングリスト(posting list))の組み合わせの集合を格納します。 ここでポスティングリストはキーが発生した行IDの集合です。 項目は1つ以上のキーを含むことができますので、同じ行IDが複数のポスティングリストに現れることがあり得ます。 キー値はそれぞれ一度のみ格納されます。 このためGINインデックスの容量は、同じキーが何度も現れる場合に非常に小さくなります。
<acronym>GIN</acronym> is generalized in the sense that the <acronym>GIN</acronym> access method code does not need to know the specific operations that it accelerates. Instead, it uses custom strategies defined for particular data types. The strategy defines how keys are extracted from indexed items and query conditions, and how to determine whether a row that contains some of the key values in a query actually satisfies the query. GINインデックスは、GINアクセスメソッドが高速化対象の操作を把握する必要がないという意味で汎用化されています。 その代わり、特定のデータ型に対して定義された独自の戦略を使用します。 戦略は、インデックス付けされた項目と問い合わせ条件からキーを抽出する方法および問い合わせ内のいくつかのキー値を含む行が実際に問い合わせを満たすかどうかを決定する方法を定義します。
One advantage of <acronym>GIN</acronym> is that it allows the development of custom data types with the appropriate access methods, by an expert in the domain of the data type, rather than a database expert. This is much the same advantage as using <acronym>GiST</acronym>. GINの利点の1つは、データベース専門家ではなくデータ型の分野における専門家により、適切なアクセスメソッドを持つ独自のデータ型を開発できるという点です。 これはGiSTの使用とほぼ同じ利点です。
The <acronym>GIN</acronym> implementation in <productname>PostgreSQL</productname> is primarily maintained by Teodor Sigaev and Oleg Bartunov. There is more information about <acronym>GIN</acronym> on their <ulink url="http://www.sai.msu.su/~megera/wiki/Gin">website</ulink>. PostgreSQLにおけるGINの実装は、主にTeodor SigaevとOleg Bartunovにより保守されています。 GINに関する情報は彼らのwebサイトにより多く記載されています。
The core <productname>PostgreSQL</productname> distribution includes the <acronym>GIN</acronym> operator classes shown in <xref linkend="gin-builtin-opclasses-table"/>. (Some of the optional modules described in <xref linkend="contrib"/> provide additional <acronym>GIN</acronym> operator classes.) PostgreSQLのコア配布物は表 64.3に示すGIN演算子クラスを含みます。 (付録Fに記載された追加モジュールの中には追加のGIN演算子クラスを提供するものもあります。)
表64.3 組み込みGIN演算子クラス
名前 | インデックス可能な演算子 |
---|---|
array_ops | && (anyarray,anyarray) |
@> (anyarray,anyarray) | |
<@ (anyarray,anyarray) | |
= (anyarray,anyarray) | |
jsonb_ops | @> (jsonb,jsonb) |
@? (jsonb,jsonpath) | |
@@ (jsonb,jsonpath) | |
? (jsonb,text) | |
?| (jsonb,text[]) | |
?& (jsonb,text[]) | |
jsonb_path_ops | @> (jsonb,jsonb) |
@? (jsonb,jsonpath) | |
@@ (jsonb,jsonpath) | |
tsvector_ops | @@ (tsvector,tsquery) |
Of the two operator classes for type <type>jsonb</type>, <literal>jsonb_ops</literal>
is the default. <literal>jsonb_path_ops</literal> supports fewer operators but
offers better performance for those operators.
See <xref linkend="json-indexing"/> for details.
jsonb
型の2つの演算子クラスのうち、jsonb_ops
がデフォルトです。
jsonb_path_ops
はより少数の演算子しかサポートしませんが、その演算子に対してはより良いパフォーマンスを提供します。
詳細は8.14.4を参照してください。
The <acronym>GIN</acronym> interface has a high level of abstraction, requiring the access method implementer only to implement the semantics of the data type being accessed. The <acronym>GIN</acronym> layer itself takes care of concurrency, logging and searching the tree structure. GINインタフェースは高度に抽象化されています。 アクセスメソッド実装者に要求されることは、アクセスするデータ型の意味を実装することだけです。 GIN層自体が同時実行性、ログ処理、ツリー構造の検索処理に関する面倒を見ます。
All it takes to get a <acronym>GIN</acronym> access method working is to implement a few user-defined methods, which define the behavior of keys in the tree and the relationships between keys, indexed items, and indexable queries. In short, <acronym>GIN</acronym> combines extensibility with generality, code reuse, and a clean interface. GINアクセスメソッドを動作させるために必要なことは、少数のユーザ定義関数を実装することだけです。 これは、ツリー内のキーの動作とキーとインデックス付けされる項目、インデックス可能な問い合わせ間の関係を定義します。 すなわち、GINは、一般化、コード再利用、整理されたインタフェースによる拡張性を組み合わせます。
There are two methods that an operator class for <acronym>GIN</acronym> must provide: GIN用の演算子クラスが提供しなければならないメソッドは2つあります。
Datum *extractValue(Datum itemValue, int32 *nkeys,
bool **nullFlags)
Returns a palloc'd array of keys given an item to be indexed. The
number of returned keys must be stored into <literal>*nkeys</literal>.
If any of the keys can be null, also palloc an array of
<literal>*nkeys</literal> <type>bool</type> fields, store its address at
<literal>*nullFlags</literal>, and set these null flags as needed.
<literal>*nullFlags</literal> can be left <symbol>NULL</symbol> (its initial value)
if all keys are non-null.
The return value can be <symbol>NULL</symbol> if the item contains no keys.
インデックス対象値に与えられる、pallocで割り当てられたキーの配列を返します。
返されるキーの数は*nkeys
に格納しなければなりません。
キーのいずれかがNULLになるかもしれない場合、*nkeys
個のbool
の配列をpallocで割り当てそのアドレスを*nullFlags
に格納し、必要に応じてNULLフラグを設定してください。
すべてのキーが非NULLであれば、*nullFlags
をNULL
(初期値)のままにすることができます。
項目がキーを含まない場合、戻り値はNULL
になるかもしれません。
Datum *extractQuery(Datum query, int32 *nkeys,
StrategyNumber n, bool **pmatch, Pointer **extra_data,
bool **nullFlags, int32 *searchMode)
Returns a palloc'd array of keys given a value to be queried; that is,
<literal>query</literal> is the value on the right-hand side of an
indexable operator whose left-hand side is the indexed column.
<literal>n</literal> is the strategy number of the operator within the
operator class (see <xref linkend="xindex-strategies"/>).
Often, <function>extractQuery</function> will need
to consult <literal>n</literal> to determine the data type of
<literal>query</literal> and the method it should use to extract key values.
The number of returned keys must be stored into <literal>*nkeys</literal>.
If any of the keys can be null, also palloc an array of
<literal>*nkeys</literal> <type>bool</type> fields, store its address at
<literal>*nullFlags</literal>, and set these null flags as needed.
<literal>*nullFlags</literal> can be left <symbol>NULL</symbol> (its initial value)
if all keys are non-null.
The return value can be <symbol>NULL</symbol> if the <literal>query</literal> contains no keys.
問い合わせ対象の値に与えられる、pallocで割り当てられたキーの配列を返します。
つまり、query
はインデックス可能な演算子の右辺の値です。
この左辺はインデックス対象の列です。
n
は演算子クラス内の演算子の戦略番号です(36.16.2を参照)。
extractQuery
はしばしば、query
のデータ型とキー値を抽出するために使用しなければならないメソッドを決定するために、n
を調べなければなりません。
返されるキーの数を*nkeys
に格納しなければなりません。
キーのいずれかがNULLとなる可能性がある場合はまた、*nkeys
個のbool
の配列をpallocで割り当て、*nullFlags
にそのアドレスを格納し、必要に応じてNULLフラグを設定してください。
すべてのキーが非NULLならば*nullFlags
はNULL
(初期値)のままにしておくことができます。
query
がキーを含まない場合、戻り値をNULL
にすることができます。
<literal>searchMode</literal> is an output argument that allows
<function>extractQuery</function> to specify details about how the search
will be done.
If <literal>*searchMode</literal> is set to
<literal>GIN_SEARCH_MODE_DEFAULT</literal> (which is the value it is
initialized to before call), only items that match at least one of
the returned keys are considered candidate matches.
If <literal>*searchMode</literal> is set to
<literal>GIN_SEARCH_MODE_INCLUDE_EMPTY</literal>, then in addition to items
containing at least one matching key, items that contain no keys at
all are considered candidate matches. (This mode is useful for
implementing is-subset-of operators, for example.)
If <literal>*searchMode</literal> is set to <literal>GIN_SEARCH_MODE_ALL</literal>,
then all non-null items in the index are considered candidate
matches, whether they match any of the returned keys or not. (This
mode is much slower than the other two choices, since it requires
scanning essentially the entire index, but it may be necessary to
implement corner cases correctly. An operator that needs this mode
in most cases is probably not a good candidate for a GIN operator
class.)
The symbols to use for setting this mode are defined in
<filename>access/gin.h</filename>.
searchMode
は出力引数です。
これによりextractQuery
は検索がどのように行われるかの詳細を指定することができます。
*searchMode
がGIN_SEARCH_MODE_DEFAULT
(呼び出し前にこの値に初期化されます。)に設定された場合、返されるキーの少なくとも1つに一致する項目が合致候補とみなされます。
*searchMode
がGIN_SEARCH_MODE_INCLUDE_EMPTY
に設定された場合、少なくとも1つの一致するキーを含む項目に加え、キーをまったく含まない項目が合致候補とみなされます。
(このモードは例えば何のサブセットかを求める演算子を実装する際に有用です。)
*searchMode
がGIN_SEARCH_MODE_ALL
に設定された場合、返されるキーのいずれかに一致するかどうかは関係なく、インデックス内の非NULLの項目すべてが合致候補とみなされます。
(このモードは、基本的にインデックス全体のスキャン処理が必要ですので、他の2つの選択肢と比べてかなり低速になります。
しかし境界条件を正確に実装するためにこれが必要になるかもしれません。
おそらく、このモードを必要とする演算子はほとんどの場合、GIN演算子クラス向けに優れた候補ではありません。)
このモードを設定するために使用する記号はaccess/gin.h
で定義されています。
<literal>pmatch</literal> is an output argument for use when partial match
is supported. To use it, <function>extractQuery</function> must allocate
an array of <literal>*nkeys</literal> <type>bool</type>s and store its address at
<literal>*pmatch</literal>. Each element of the array should be set to true
if the corresponding key requires partial match, false if not.
If <literal>*pmatch</literal> is set to <symbol>NULL</symbol> then GIN assumes partial match
is not required. The variable is initialized to <symbol>NULL</symbol> before call,
so this argument can simply be ignored by operator classes that do
not support partial match.
pmatch
は部分一致が提供されている場合に使用する出力引数です。
使用するには、extractQuery
が*nkeys
個のbool
の配列を割り当て、そのアドレスを*pmatch
に格納しなければなりません。
関連するキーが部分一致を必要とするとき、それぞれの配列要素は真に、そうでなければ偽に設定されなければなりません。
*pmatch
がNULL
に設定されている場合、GINは部分一致が必要ないと想定します。
呼び出し前に変数はNULL
に初期化されますので、この引数は部分一致が提供されていない演算子クラスでは、単に無視できます。
<literal>extra_data</literal> is an output argument that allows
<function>extractQuery</function> to pass additional data to the
<function>consistent</function> and <function>comparePartial</function> methods.
To use it, <function>extractQuery</function> must allocate
an array of <literal>*nkeys</literal> pointers and store its address at
<literal>*extra_data</literal>, then store whatever it wants to into the
individual pointers. The variable is initialized to <symbol>NULL</symbol> before
call, so this argument can simply be ignored by operator classes that
do not require extra data. If <literal>*extra_data</literal> is set, the
whole array is passed to the <function>consistent</function> method, and
the appropriate element to the <function>comparePartial</function> method.
extra_data
は、extractQuery
がconsistent
とcomparePartial
メソッドに追加データを渡すことができるようにする出力引数です。
使用するには、extractQuery
が*nkeys
ポインタの配列を割り当て、そのアドレスを*extra_data
に格納し、そして望まれるものは何でも個別のポインタに格納しなければなりません。
変数は呼び出し前にNULL
に初期化されますので、追加データを必要としない演算子クラスでこの引数は単に無視できます。
もし*extra_data
が設定されれば、配列全部がconsistent
メソッドに、適切な要素がcomparePartial
メソッドに渡されます。
An operator class must also provide a function to check if an indexed item
matches the query. It comes in two flavors, a Boolean <function>consistent</function>
function, and a ternary <function>triConsistent</function> function.
<function>triConsistent</function> covers the functionality of both, so providing
<function>triConsistent</function> alone is sufficient. However, if the Boolean
variant is significantly cheaper to calculate, it can be advantageous to
provide both. If only the Boolean variant is provided, some optimizations
that depend on refuting index items before fetching all the keys are
disabled.
演算子クラスは、インデックス付けされた項目が問い合わせに一致するか確認する関数も提供しなければなりません。
それは2つの方法で行なわれます。
2値のconsistent
関数と3値のtriConsistent
関数です。
triConsistent
が両方の機能を含みますので、triConsistent
だけを提供しても十分です。
しかし、2値の亜種を計算するのが著しく安価であれば、両方を提供することは役に立つかもしれません。
2値の亜種のみが提供されていれば、すべてのキーを取得する前にインデックス項目が一致しないことを確認することに基づく最適化の中には無効となるものもあります。
bool consistent(bool check[], StrategyNumber n, Datum query,
int32 nkeys, Pointer extra_data[], bool *recheck,
Datum queryKeys[], bool nullFlags[])
Returns true if an indexed item satisfies the query operator with
strategy number <literal>n</literal> (or might satisfy it, if the recheck
indication is returned). This function does not have direct access
to the indexed item's value, since <acronym>GIN</acronym> does not
store items explicitly. Rather, what is available is knowledge
about which key values extracted from the query appear in a given
indexed item. The <literal>check</literal> array has length
<literal>nkeys</literal>, which is the same as the number of keys previously
returned by <function>extractQuery</function> for this <literal>query</literal> datum.
Each element of the
<literal>check</literal> array is true if the indexed item contains the
corresponding query key, i.e., if (check[i] == true) the i-th key of the
<function>extractQuery</function> result array is present in the indexed item.
The original <literal>query</literal> datum is
passed in case the <function>consistent</function> method needs to consult it,
and so are the <literal>queryKeys[]</literal> and <literal>nullFlags[]</literal>
arrays previously returned by <function>extractQuery</function>.
<literal>extra_data</literal> is the extra-data array returned by
<function>extractQuery</function>, or <symbol>NULL</symbol> if none.
インデックス付けられた項目が戦略番号n
を持つ問い合わせ演算子を満たす(または、recheck印が返されたときはたぶん満たすかもしれない)場合に真を返します。
GINは項目を明示的に格納しませんので、この関数はインデックス付けされた項目の値に直接アクセスすることができません。
どちらかというと、この問い合わせから取り出される指定された問い合わせで現れるキー値に関する知識が利用できるものです。
check
配列は長さnkeys
であり、このquery
データに対して事前に行われたextractQuery
が返したキーの数と同じです。
インデックス対象の項目が対応する問い合わせキーを持つ場合、check
配列の各要素は真です。
つまり、(check[i] == true)の場合、extractQuery
の結果配列のi番目のキーがインデックス対象項目内に存在します。
元のquery
データは、consistent
メソッドがそれを調査する必要がある場合に、渡されます。
このためqueryKeys[]
およびnullFlags[]
は事前にextractQuery
によって返されます。
extra_data
はextractQuery
により返された追加データ配列で、ない場合はNULL
です。
When <function>extractQuery</function> returns a null key in
<literal>queryKeys[]</literal>, the corresponding <literal>check[]</literal> element
is true if the indexed item contains a null key; that is, the
semantics of <literal>check[]</literal> are like <literal>IS NOT DISTINCT
FROM</literal>. The <function>consistent</function> function can examine the
corresponding <literal>nullFlags[]</literal> element if it needs to tell
the difference between a regular value match and a null match.
extractQuery
がqueryKeys[]
内でNULLキーを返す時、インデックス対象項目がNULLキーを含む場合は対応するcheck[]
要素は真です、
つまり、check[]
の意味はIS NOT DISTINCT FROM
のようなものです。
consistent
関数は、通常の値の合致とNULL合致との違いを通知する必要がある場合、対応するnullFlags[]
要素を検査することができます。
On success, <literal>*recheck</literal> should be set to true if the heap
tuple needs to be rechecked against the query operator, or false if
the index test is exact. That is, a false return value guarantees
that the heap tuple does not match the query; a true return value with
<literal>*recheck</literal> set to false guarantees that the heap tuple does
match the query; and a true return value with
<literal>*recheck</literal> set to true means that the heap tuple might match
the query, so it needs to be fetched and rechecked by evaluating the
query operator directly against the originally indexed item.
成功の場合、*recheck
は、問い合わせ演算子に対してヒープタプルを再検査する必要があればtrue、インデックス検査が的確であればfalseに設定する必要があります。
つまり、falseの戻り値はヒープタプルが問い合わせに一致しないことを保証します。
trueの戻り値で、*recheck
がfalseに設定された場合はヒープタプルが問い合わせに一致することを保証します。
trueの戻り値で、*recheck
がtrueに設定された場合はヒープタプルが問い合わせに一致する可能性があることを意味します。
したがって、それを取り出し、元のインデックス付けされた項目を直接問い合わせ演算子で評価することで再検査する必要があることを意味します。
GinTernaryValue triConsistent(GinTernaryValue check[], StrategyNumber n, Datum query,
int32 nkeys, Pointer extra_data[],
Datum queryKeys[], bool nullFlags[])
<function>triConsistent</function> is similar to <function>consistent</function>,
but instead of Booleans in the <literal>check</literal> vector, there are
three possible values for each
key: <literal>GIN_TRUE</literal>, <literal>GIN_FALSE</literal> and
<literal>GIN_MAYBE</literal>. <literal>GIN_FALSE</literal> and <literal>GIN_TRUE</literal>
have the same meaning as regular Boolean values, while
<literal>GIN_MAYBE</literal> means that the presence of that key is not known.
When <literal>GIN_MAYBE</literal> values are present, the function should only
return <literal>GIN_TRUE</literal> if the item certainly matches whether or
not the index item contains the corresponding query keys. Likewise, the
function must return <literal>GIN_FALSE</literal> only if the item certainly
does not match, whether or not it contains the <literal>GIN_MAYBE</literal>
keys. If the result depends on the <literal>GIN_MAYBE</literal> entries, i.e.,
the match cannot be confirmed or refuted based on the known query keys,
the function must return <literal>GIN_MAYBE</literal>.
triConsistent
はconsistent
と似ていますが、check
ベクターの論理値の代わりに、各キーに対して3つの可能な値があります。GIN_TRUE
、GIN_FALSE
、GIN_MAYBE
です。
GIN_FALSE
とGIN_TRUE
は通常の論理値と同じ意味であり、GIN_MAYBE
はそのキーの存在が分からないこと意味します。
GIN_MAYBE
値があれば、インデックス項目が対応する問い合わせキーを含むかどうかに関わらず、項目が確実に一致する場合にのみ関数はGIN_TRUE
を返すべきです。
同様に、GIN_MAYBE
を含むかどうかに関わらず項目が確実に一致しない場合にのみ関数はGIN_FALSE
を返さなければなりません。
結果がGIN_MAYBE
項目に依存する、すなわち、分かっている問い合わせキーに基づいて、一致することもしないことも確認できない場合には、関数はGIN_MAYBE
を返さなければなりません。
When there are no <literal>GIN_MAYBE</literal> values in the <literal>check</literal>
vector, a <literal>GIN_MAYBE</literal> return value is the equivalent of
setting the <literal>recheck</literal> flag in the
Boolean <function>consistent</function> function.
check
ベクターにGIN_MAYBE
値がなければ、GIN_MAYBE
戻り値は論理値のconsistent
関数でrecheck
フラグを設定することと同じです。
In addition, GIN must have a way to sort the key values stored in the index. The operator class can define the sort ordering by specifying a comparison method: さらに、GINにはインデックス内に格納されているキー値をソートする方法がなければなりません。 演算子クラスは比較メソッドを指定することでソート順を定義できます。
int compare(Datum a, Datum b)
Compares two keys (not indexed items!) and returns an integer less than zero, zero, or greater than zero, indicating whether the first key is less than, equal to, or greater than the second. Null keys are never passed to this function. キー(インデックス付けされる項目ではありません)を比較し、0より小さい、0、または0より大きい整数を返します。 それぞれ、最初のキーが2番目のキーより、小さい、等しい、または大きいことを示します。 NULLキーがこの関数に渡されることはありません。
Alternatively, if the operator class does not provide a <function>compare</function>
method, GIN will look up the default btree operator class for the index
key data type, and use its comparison function. It is recommended to
specify the comparison function in a GIN operator class that is meant for
just one data type, as looking up the btree operator class costs a few
cycles. However, polymorphic GIN operator classes (such
as <literal>array_ops</literal>) typically cannot specify a single comparison
function.
あるいは、演算子クラスがcompare
メソッドを提供しない場合には、GINはそのインデックスキーデータ型に対するデフォルトのbtree演算子クラスを探し、その比較関数を使います。
btree演算子クラスを探すのは処理に多少掛かりますので、GIN演算子クラスの中で比較関数を指定することを勧めます。それはただ一つのデータ型に対するものであることを意味します。
しかし、(array_ops
のような)多様GIN演算子クラスでは、通常は単一の比較関数を指定できません。
An operator class for <acronym>GIN</acronym> can optionally supply the following methods: 省略可能ですが、GINに対する演算子クラスは以下のメソッドを提供します。
int comparePartial(Datum partial_key, Datum key, StrategyNumber n,
Pointer extra_data)
Compare a partial-match query key to an index key. Returns an integer
whose sign indicates the result: less than zero means the index key
does not match the query, but the index scan should continue; zero
means that the index key does match the query; greater than zero
indicates that the index scan should stop because no more matches
are possible. The strategy number <literal>n</literal> of the operator
that generated the partial match query is provided, in case its
semantics are needed to determine when to end the scan. Also,
<literal>extra_data</literal> is the corresponding element of the extra-data
array made by <function>extractQuery</function>, or <symbol>NULL</symbol> if none.
Null keys are never passed to this function.
問い合わせキーとインデックスキーの部分一致を比較します。
符号が結果を示す整数が返ります。
ゼロ未満はインデックスキーは問い合わせに一致しないが、インデックススキャンを続けるべきであることを示します。
ゼロはインデックスキーが問い合わせに一致することを示します。
ゼロより大きな値はこれ以上の一致はありえないためインデックススキャンを停止すべきであることを示します。
スキャンをいつ停止するかを決めるためにセマンティクスが必要とされる場合、部分一致問い合わせを生成した演算子の戦略番号n
が提供されます。
またextra_data
はextractQuery
で作成される追加データ配列の対応する要素、もしなければNULL
です。
NULLキーがこの関数に渡されることはありません。
void options(local_relopts *relopts)
Defines a set of user-visible parameters that control operator class behavior. 演算子クラスの振舞いを制御するユーザに可視のパラメータの集合を定義します。
The <function>options</function> function is passed a pointer to a
<structname>local_relopts</structname> struct, which needs to be
filled with a set of operator class specific options. The options
can be accessed from other support functions using the
<literal>PG_HAS_OPCLASS_OPTIONS()</literal> and
<literal>PG_GET_OPCLASS_OPTIONS()</literal> macros.
options
関数にはlocal_relopts
構造体へのポインタが渡されますが、構造体を演算子クラスに固有のオプションの集合で満たすことが必要です。
オプションはマクロPG_HAS_OPCLASS_OPTIONS()
とPG_GET_OPCLASS_OPTIONS()
を使って他のサポート関数からアクセスできます。
Since both key extraction of indexed values and representation of the key in <acronym>GIN</acronym> are flexible, they may depend on user-specified parameters. インデックス付けされた値からのキーの抽出にもGINでのキーの表現にも柔軟性がありますので、ユーザに固有のパラメータに依存するかもしれません。
To support <quote>partial match</quote> queries, an operator class must
provide the <function>comparePartial</function> method, and its
<function>extractQuery</function> method must set the <literal>pmatch</literal>
parameter when a partial-match query is encountered. See
<xref linkend="gin-partial-match"/> for details.
「部分一致」問い合わせをサポートするためには、演算子クラスはcomparePartial
メソッドを提供しなければなりません。
またそのextractQuery
は、部分一致問い合わせであった時にpmatch
パラメータを設定しなければなりません。
詳細については64.4.4.2を参照してください。
The actual data types of the various <literal>Datum</literal> values mentioned
above vary depending on the operator class. The item values passed to
<function>extractValue</function> are always of the operator class's input type, and
all key values must be of the class's <literal>STORAGE</literal> type. The type of
the <literal>query</literal> argument passed to <function>extractQuery</function>,
<function>consistent</function> and <function>triConsistent</function> is whatever is the
right-hand input type of the class member operator identified by the
strategy number. This need not be the same as the indexed type, so long as
key values of the correct type can be extracted from it. However, it is
recommended that the SQL declarations of these three support functions use
the opclass's indexed data type for the <literal>query</literal> argument, even
though the actual type might be something else depending on the operator.
上記の各種Datum
値の実データ型は、演算子クラスに依存して変動します。
extractValue
に渡される項目値は常に演算子クラスの入力型であり、キー値はすべてそのクラスのSTORAGE
型でなければなりません。
extractQuery
、consistent
およびtriConsistent
に渡されるquery
引数の型は、戦略番号によって識別されるクラスのメンバ演算子の右辺入力型です。
正しい型のキー値がそこから抽出できる限り、これはインデックス付けされた型と同じである必要はありません。
しかしながら、この3つのサポート関数のSQL宣言では、実際の型は演算子に依存して何か他のものであるとしても、query
引数には演算子クラスのインデックス付けされたデータ型を使うことを勧めます。
Internally, a <acronym>GIN</acronym> index contains a B-tree index constructed over keys, where each key is an element of one or more indexed items (a member of an array, for example) and where each tuple in a leaf page contains either a pointer to a B-tree of heap pointers (a <quote>posting tree</quote>), or a simple list of heap pointers (a <quote>posting list</quote>) when the list is small enough to fit into a single index tuple along with the key value. <xref linkend="gin-internals-figure"/> illustrates these components of a GIN index. GINインデックスはキー全体に対するB-treeインデックスを持ちます。 そのキーはそれぞれインデックス対象項目の要素(例えば配列のメンバ)であり、リーフページ内のタプルはそれぞれ、ヒープポインタのB-treeへのポインタ(「ポスティングツリー(posting tree)」)か、もしリストがキー値と共に単一インデックスタプルに合う程度十分に小さければヒープポインタの単純なリスト(「ポスティングリスト(posting list)」)です。 図 64.1にGINインデックスのこれらのコンポーネントを示します。
As of <productname>PostgreSQL</productname> 9.1, null key values can be
included in the index. Also, placeholder nulls are included in the index
for indexed items that are null or contain no keys according to
<function>extractValue</function>. This allows searches that should find empty
items to do so.
PostgreSQL 9.1からNULLキー値をインデックスに含められるようになりました。
またプレースホルダとしてのNULLが、NULLまたはextractValue
によるとキーを含まないインデックス対象項目についてインデックスに含められます。
これにより空の項目を見つけ出すための検索を行うことができます。
Multicolumn <acronym>GIN</acronym> 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. 複数列に対するGINインデックスは複合型の値(列番号、キー値)全体について単一のB-treeを構築することで実装されます。 異なる列に対するキー値は別の型となるかもしれません。
図64.1 GINの内部
Updating a <acronym>GIN</acronym> 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).
<acronym>GIN</acronym> 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 when
<function>gin_clean_pending_list</function> function is called, or if the
pending list becomes larger than
<xref linkend="guc-gin-pending-list-limit"/>, the entries are moved to the
main <acronym>GIN</acronym> data structure using the same bulk insert
techniques used during initial index creation. This greatly improves
<acronym>GIN</acronym> 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.
1つのヒープ行の挿入または更新によりインデックスへの挿入が多く発生するという、転置インデックスの本質的な性質のためGINインデックスの更新は低速になりがちです。
(各キー用のヒープ行はインデックス付けされた項目から取り出されます。)
GINは、新しいタプルを一時的なソートされていない、待機中の項目リストに挿入することにより、この作業の大部分を遅延させることができるようになりました。
テーブルがバキュームまたは自動解析された時、gin_clean_pending_list
関数が呼ばれたとき、または、待機中のリスト(pending list)がgin_pending_list_limitよりも大きくなった時、初期のインデックス作成の際に使用されるものと同様の一括挿入技法を使用して、項目は主GINデータ構造に移動されます。
これは、バキュームのオーバーヘッドが追加されることを考慮したとしても、GINインデックスの更新速度を著しく向上します。
さらに、フォアグラウンドの問い合わせ処理ではなくバックグラウンド処理でこのオーバーヘッド作業を実行することができます。
The main disadvantage of this approach is that searches must scan the list of pending entries in addition to searching the regular index, and so a large list of pending entries will slow searches significantly. Another disadvantage is that, while most updates are fast, an update that causes the pending list to become <quote>too large</quote> will incur an immediate cleanup cycle and thus be much slower than other updates. Proper use of autovacuum can minimize both of these problems. この手法の大きな欠点は、検索時に通常のインデックス検索に加え待機中の項目リストのスキャンを行わなければならない点です。 このため、待機中の項目リストが大きくなると検索が顕著に遅くなります。 他の欠点は、ほとんどの更新は高速ですが、待機中の項目リストが「大きくなりすぎる」きっかけとなった更新は即時の整理処理を招くことになり、他の更新に比べ大きく低速になります。 自動バキュームを適切に使用することで、これらの両方の問題を最小化することができます。
If consistent response time is more important than update speed,
use of pending entries can be disabled by turning off the
<literal>fastupdate</literal> storage parameter for a
<acronym>GIN</acronym> index. See <xref linkend="sql-createindex"/>
for details.
一貫した応答時間が更新速度より重要な場合、GINインデックスに対するfastupdate
格納パラメータを無効にすることにより、待機中の項目の使用を無効にすることができます。
詳細はCREATE INDEXを参照してください。
GIN can support <quote>partial match</quote> 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 the <function>compare</function> support method).
The <function>extractQuery</function> 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 the <literal>pmatch</literal> flag true.
The key range is then scanned using the <function>comparePartial</function>
method. <function>comparePartial</function> 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.
GINは「部分一致」問い合わせをサポートすることができます。
この問い合わせは1つ以上のキーに正確に一致することは決定しませんが、キー値の合理的に狭い(compare
サポートメソッドで決まるキーのソート順に従った)範囲内に一致する可能性があります。
extractQuery
は、正確に一致したキー値を返す代わりに、検索される範囲の下限となるキー値を返し、pmatch
フラグを真に設定します。
そしてキー範囲をcomparePartial
メソッドを使用して検索します。
comparePartial
は一致するインデックスキーではゼロを、一致しないが検索すべき範囲内にあればゼロ未満の値を、インデックスキーが一致可能な範囲を超えた場合はゼロより大きな値を返さなければなりません。
Insertion into a <acronym>GIN</acronym> index can be slow due to the likelihood of many keys being inserted for each item. So, for bulk insertions into a table it is advisable to drop the GIN index and recreate it after finishing bulk insertion. 各項目に対して多くのキーが挿入される可能性がありますので、GINインデックスへの挿入は低速になることがあります。 ですので、テーブルに対する大量の挿入では、GINインデックスを削除し、大量の挿入が終わった段階で再作成することを勧めます。
When <literal>fastupdate</literal> is enabled for <acronym>GIN</acronym>
(see <xref linkend="gin-fast-update"/> for details), the penalty is
less than when it is not. But for very large updates it may still be
best to drop and recreate the index.
GINではfastupdate
が有効である場合、このペナルティはそうでない場合よりも少なくなります。
(64.4.4.1を参照してください。)
しかし非常に大規模な更新では、インデックスの削除と再作成がまだ最善かもしれません。
Build time for a <acronym>GIN</acronym> index is very sensitive to
the <varname>maintenance_work_mem</varname> setting; it doesn't pay to
skimp on work memory during index creation.
GINインデックスの構築時間はmaintenance_work_mem
の設定に非常に敏感です。
インデックス作成時に作業メモリをより少なく使用しようとはしません。
During a series of insertions into an existing <acronym>GIN</acronym>
index that has <literal>fastupdate</literal> enabled, the system will clean up
the pending-entry list whenever the list grows larger than
<varname>gin_pending_list_limit</varname>. To avoid fluctuations in observed
response time, it's desirable to have pending-list cleanup occur in the
background (i.e., via autovacuum). Foreground cleanup operations
can be avoided by increasing <varname>gin_pending_list_limit</varname>
or making autovacuum more aggressive.
However, enlarging the threshold of the cleanup operation means that
if a foreground cleanup does occur, it will take even longer.
fastupdate
が有効な既存のGINインデックスに対して挿入を繰り返す間、待機中の項目リストがgin_pending_list_limit
より大きくなると、システムはこのリストを整理します。
観測される応答時間の変動を防ぐためには、待機中リストの整理をバックグラウンド(すなわち自動バキューム)で起きるようにすることが望まれます。
フォアグラウンドでの整理処理は、gin_pending_list_limit
を大きくすること、もしくは自動バキュームをより積極的に行うことで防ぐことができます。
しかし、整理処理の閾値を大きくすることは、フォアグラウンドで整理処理が発生した時により長い時間がかかることを意味します。
<varname>gin_pending_list_limit</varname> can be overridden for individual
GIN indexes by changing storage parameters, which allows each
GIN index to have its own cleanup threshold.
For example, it's possible to increase the threshold only for the GIN
index which can be updated heavily, and decrease it otherwise.
gin_pending_list_limit
は格納パラメータを変更することで個々のGINインデックスに対して上書きでき、それにより各GINインデックスが自身の整理閾値を持てます。
例えば、頻繁に更新される可能性のあるGINインデックスの閾値のみを増やして、それ以外は減らすことができます。
The primary goal of developing <acronym>GIN</acronym> indexes was to create support for highly scalable full-text search in <productname>PostgreSQL</productname>, and there are often situations when a full-text search returns a very large set of results. Moreover, this often happens when the query contains very frequent words, so that the large result set is not even useful. Since reading many tuples from the disk and sorting them could take a lot of time, this is unacceptable for production. (Note that the index search itself is very fast.) GINインデックス開発の主な目的は、スケーラビリティが高い全文検索のサポートをPostgreSQLで作成することでした。 全文検索の結果は非常に大規模な結果セットを返します。 さらに、問い合わせが非常に高頻度な単語を持つ場合、こうした状況はよく発生しますが、大規模な結果セットは有用ですらありません。 ディスクから大量のタプルを読み、ソートすることは長い時間がかかりますので、実運用レベルでは受け入れられません。 (インデックス検索自体は非常に高速であることに注意してください。)
To facilitate controlled execution of such queries,
<acronym>GIN</acronym> has a configurable soft upper limit on the
number of rows returned: the
<varname>gin_fuzzy_search_limit</varname> configuration parameter.
It is set to 0 (meaning no limit) by default.
If a non-zero limit is set, then the returned set is a subset of
the whole result set, chosen at random.
こうした問い合わせの実行を簡単に制御できるように、GINは返される行数に対して設定可能なソフト上限、gin_fuzzy_search_limit
設定パラメータを持ちます。
これはデフォルトでは0です(無制限を意味します)。
非0の制限が設定された場合、返されるセットは結果セット全体からランダムに選んだサブセットになります。
<quote>Soft</quote> means that the actual number of returned results could differ somewhat from the specified limit, depending on the query and the quality of the system's random number generator. 「ソフト」は、問い合わせとシステムの乱数ジェネレータの品質に依存して、返される結果の実際の数が指定した上限より多少異なることを意味します。
From experience, values in the thousands (e.g., 5000 — 20000) work well. 経験上、数千(例えば5000から20000)の値がうまく動作します。
<acronym>GIN</acronym> assumes that indexable operators are strict. This
means that <function>extractValue</function> will not be called at all on a null
item value (instead, a placeholder index entry is created automatically),
and <function>extractQuery</function> will not be called on a null query
value either (instead, the query is presumed to be unsatisfiable). Note
however that null key values contained within a non-null composite item
or query value are supported.
GINは、インデックス付け可能な演算子は厳密であると仮定します。
これはextractValue
はNULL項目値についてはまったく呼び出されない(代わりにインデックス項目のプレースホルダが自動的に生成される)こと、および、extractQuery
は問い合わせの値がNULLの場合に呼び出されない(代わりに問い合わせは不一致であるとみなされる)ことを意味します。
しかし非NULLの複合型項目内または問い合わせ値内のNULLキー値はサポートされます。
The core <productname>PostgreSQL</productname> distribution
includes the <acronym>GIN</acronym> operator classes previously shown in
<xref linkend="gin-builtin-opclasses-table"/>.
The following <filename>contrib</filename> modules also contain
<acronym>GIN</acronym> operator classes:
PostgreSQLのコア配布物は以前表 64.3に示したGIN演算子クラスを含みます。
以下のcontrib
モジュールにもGIN演算子クラスが含まれています。
btree_gin
さまざまなデータ型に対するB-tree等価の機能
hstore
(キー、値)の組み合わせを格納するモジュール
intarray
int[]
に対する高度サポート
pg_trgm
トライグラム一致を使用したテキスト類似度