In an index scan, the index access method is responsible for regurgitating the TIDs of all the tuples it has been told about that match the <firstterm>scan keys</firstterm>. The access method is <emphasis>not</emphasis> involved in actually fetching those tuples from the index's parent table, nor in determining whether they pass the scan's visibility test or other conditions. インデックススキャンでは、スキャンキーに一致するものと示したすべてのタプルのTIDを繰り返すことに関する責任をインデックスアクセスメソッドが持ちます。 アクセスメソッドには、実際のインデックスの親テーブルからのタプルの取り出しやタプルがスキャンの可視性テストや他の条件を通過したかどうかの決定は含まれません。
A scan key is the internal representation of a <literal>WHERE</literal> clause of
the form <replaceable>index_key</replaceable> <replaceable>operator</replaceable>
<replaceable>constant</replaceable>, where the index key is one of the columns of the
index and the operator is one of the members of the operator family
associated with that index column. An index scan has zero or more scan
keys, which are implicitly ANDed — the returned tuples are expected
to satisfy all the indicated conditions.
スキャンキーは、index_key
operator
constant
という形式のWHERE
句の内部的表現です。
ここで、index_key
は、インデックス列の1つで、operator
はインデックス列に関連した演算子族のメンバの1つです。
インデックススキャンは、暗黙的にAND演算される0個以上のスキャンキーを持ちます。
返されるタプルは指定された条件を満たすものと想定されます。
The access method can report that the index is <firstterm>lossy</firstterm>, or requires rechecks, for a particular query. This implies that the index scan will return all the entries that pass the scan key, plus possibly additional entries that do not. The core system's index-scan machinery will then apply the index conditions again to the heap tuple to verify whether or not it really should be selected. If the recheck option is not specified, the index scan must return exactly the set of matching entries. アクセスメソッドはインデックスがある特定の問い合わせに対し非可逆、または再検査を要求するかどうかを報告することができます。 これは、インデックススキャンがスキャンキーを満たすすべての項目と、それに加えて、満たさない可能性のある項目を返すことを意味します。 コアシステムのインデックススキャン機構はヒープタプルに対し、本当に選択されるべきかどうかを検証するためにその演算子をインデックス条件に再度適用します。 再検査オプションが指定されない場合、インデックススキャンは一致する項目の集合を返さなければなりません。
Note that it is entirely up to the access method to ensure that it
correctly finds all and only the entries passing all the given scan keys.
Also, the core system will simply hand off all the <literal>WHERE</literal>
clauses that match the index keys and operator families, without any
semantic analysis to determine whether they are redundant or
contradictory. As an example, given
<literal>WHERE x > 4 AND x > 14</literal> where <literal>x</literal> is a b-tree
indexed column, it is left to the b-tree <function>amrescan</function> function
to realize that the first scan key is redundant and can be discarded.
The extent of preprocessing needed during <function>amrescan</function> will
depend on the extent to which the index access method needs to reduce
the scan keys to a <quote>normalized</quote> form.
確実に、指定されたスキャンキーすべてに一致するもののみをすべて正しく見つけ出すことは、完全にアクセスメソッドの責任であることに注意してください。
また、コアシステムは、冗長かどうかや矛盾するかどうかを決定するための意味的な解析を行わず、単にインデックスキーと演算子族に一致するWHERE
句をすべて渡します。
例えば、WHERE x > 4 AND x > 14
があり、x
がB-treeインデックス列であったとすると、これは、B-tree amrescan
関数に任されて、最初のスキャンキーが冗長であり、無視できることが認知されます。
amrescan
における前処理の必要性は、インデックスアクセスメソッドがスキャンキーを「正規化」形式にする必要があるかどうかに依存します。
Some access methods return index entries in a well-defined order, others do not. There are actually two different ways that an access method can support sorted output: 一部のアクセスメソッドは、他では行いませんが、十分に定義された順序でインデックス項目を返します。 アクセスメソッドが出力の順序付けをサポートできるようにする方法は、実質2種類存在します。
Access methods that always return entries in the natural ordering
of their data (such as btree) should set
<structfield>amcanorder</structfield> to true.
Currently, such access methods must use btree-compatible strategy
numbers for their equality and ordering operators.
常にそのデータ(btreeなど)の自然な順序で項目を返すアクセスメソッドはamcanorder
を真に設定しなければなりません。
現在、こうしたアクセスメソッドは、その等価性と順序付け演算子でbtree互換の戦略番号を使用しなければなりません。
Access methods that support ordering operators should set
<structfield>amcanorderbyop</structfield> to true.
This indicates that the index is capable of returning entries in
an order satisfying <literal>ORDER BY</literal> <replaceable>index_key</replaceable>
<replaceable>operator</replaceable> <replaceable>constant</replaceable>. Scan modifiers
of that form can be passed to <function>amrescan</function> as described
previously.
順序付け演算子をサポートするアクセスメソッドはamcanorderbyop
を真に設定しなければなりません。
これは、インデックスがORDER BY
index_key
operator
constant
を満たす順序で項目を返すことができることを示します。
前述の通り、この形式のスキャン修飾子をamrescan
に渡すことができます。
The <function>amgettuple</function> function has a <literal>direction</literal> argument,
which can be either <literal>ForwardScanDirection</literal> (the normal case)
or <literal>BackwardScanDirection</literal>. If the first call after
<function>amrescan</function> specifies <literal>BackwardScanDirection</literal>, then the
set of matching index entries is to be scanned back-to-front rather than in
the normal front-to-back direction, so <function>amgettuple</function> must return
the last matching tuple in the index, rather than the first one as it
normally would. (This will only occur for access
methods that set <structfield>amcanorder</structfield> to true.) After the
first call, <function>amgettuple</function> must be prepared to advance the scan in
either direction from the most recently returned entry. (But if
<structfield>amcanbackward</structfield> is false, all subsequent
calls will have the same direction as the first one.)
amgettuple
関数はdirection
引数を持ちます。
これはForwardScanDirection
(通常の場合)またはBackwardScanDirection
のいずれかを取ることができます。
amrescan
後の最初の呼び出しがBackwardScanDirection
を指定していた場合、一致したインデックス項目は通常の前から後ろという方向ではなく、後ろから前という方向でスキャンされます。
そのため、amgettuple
は通常ならばインデックス内の最初に一致したタプルを返すところですが、最後に一致したタプルを返さなければなりません。
(これはamcanorder
が真に設定されたアクセスメソッドでのみ発生します。)
最初の呼び出しの後、amgettuple
は、最も最近に返された項目からどちらの方向にスキャンを進めるかを準備しなければなりません。
(しかしamcanbackward
が偽であれば、引き続くすべての呼び出しは最初のものと同じ方向を持ちます。)
Access methods that support ordered scans must support <quote>marking</quote> a
position in a scan and later returning to the marked position. The same
position might be restored multiple times. However, only one position need
be remembered per scan; a new <function>ammarkpos</function> call overrides the
previously marked position. An access method that does not support ordered
scans need not provide <function>ammarkpos</function> and <function>amrestrpos</function>
functions in <structname>IndexAmRoutine</structname>; set those pointers to NULL
instead.
順序付けされたスキャンを提供するアクセスメソッドはスキャン内位置の「記録」をサポートしなければならず、また、後でその記録された位置に戻ることをサポートしなければなりません。
同じ位置が複数回記録されるかもしれません。
しかし、スキャン内の1つの位置のみを記録する必要があります。
新しいammarkpos
呼び出しにより前回記録された位置は上書きされます。
順序付けされたスキャンをサポートしないアクセスメソッドはIndexAmRoutine
でammarkpos
関数およびamrestrpos
関数を提供する必要はないので、これらのポインタをNULLにセットしてください。
Both the scan position and the mark position (if any) must be maintained consistently in the face of concurrent insertions or deletions in the index. It is OK if a freshly-inserted entry is not returned by a scan that would have found the entry if it had existed when the scan started, or for the scan to return such an entry upon rescanning or backing up even though it had not been returned the first time through. Similarly, a concurrent delete might or might not be reflected in the results of a scan. What is important is that insertions or deletions not cause the scan to miss or multiply return entries that were not themselves being inserted or deleted. スキャン位置と記録された位置(もしあれば)の両方は、インデックス内の同時挿入や削除という観点における一貫性を保持しなければなりません。 スキャンが始まった時に存在していた場合、項目を見つけ出したスキャンが新しく挿入された項目を返さなかったとしても問題ありません。 このような場合のスキャンでは、再スキャンやバックアップによって、あたかも最初の時点で返されたものとして項目が返されます。 同様に、同時実行削除によってスキャンの結果に影響が出るかもしれません。 重要なことは、挿入や削除によって、その項目自体が挿入・削除されていない項目がスキャンで失われたり二重になったりすることが起こらないという点です。
If the index stores the original indexed data values (and not some lossy representation of them), it is useful to support <link linkend="indexes-index-only-scans">index-only scans</link>, in which the index returns the actual data not just the TID of the heap tuple. This will only avoid I/O if the visibility map shows that the TID is on an all-visible page; else the heap tuple must be visited anyway to check MVCC visibility. But that is no concern of the access method's. インデックスが設定された列値がインデックスに格納されている(かつ、損失のある表現ではない)場合、ヒープタプルのTIDではなくインデックスに格納された実際のデータを返すインデックスオンリースキャンをサポートするのに有用です。 これは、可視性マップによってTIDが全可視のページ上にあると判断できる場合にI/Oを避けるだけのことです。 判断できない場合はMVCCを確認するためにヒープタプルにアクセスしなくてはなりません。 しかしその動作はアクセスメソッドでは考慮されていません。
Instead of using <function>amgettuple</function>, an index scan can be done with
<function>amgetbitmap</function> to fetch all tuples in one call. This can be
noticeably more efficient than <function>amgettuple</function> because it allows
avoiding lock/unlock cycles within the access method. In principle
<function>amgetbitmap</function> should have the same effects as repeated
<function>amgettuple</function> calls, but we impose several restrictions to
simplify matters. First of all, <function>amgetbitmap</function> returns all
tuples at once and marking or restoring scan positions isn't
supported. Secondly, the tuples are returned in a bitmap which doesn't
have any specific ordering, which is why <function>amgetbitmap</function> doesn't
take a <literal>direction</literal> argument. (Ordering operators will never be
supplied for such a scan, either.)
Also, there is no provision for index-only scans with
<function>amgetbitmap</function>, since there is no way to return the contents of
index tuples.
Finally, <function>amgetbitmap</function>
does not guarantee any locking of the returned tuples, with implications
spelled out in <xref linkend="index-locking"/>.
amgettuple
を使用する代わりに、amgetbitmap
を使用して、一回の呼出しですべてのタプルを取り出してインデックススキャンを行うことができます。
これはアクセスメソッド内でのロック/ロック解除という過程を防ぐことができますので、amgettuple
よりもかなり効率的です。
実際には、amgetbitmap
はamgettuple
呼び出しを繰り返すことと同じ効果を持つはずですが、物事を単純化するために複数の制限を加えています。
まず第一に、amgetbitmap
は一回ですべてのタプルを返し、スキャン位置の記録と位置戻しをサポートしません。
第二に、特定の順序付けをまったく持たないビットマップの中にタプルが返されます。
これはamgetbitmap
がdirection
引数を取らない理由です。
(順序付け演算子はこのようなスキャンでは決して与えられません。)
また、amgetbitmap
によるインデックスオンリースキャンは提供されていません。なぜなら、インデックスタプルの内容を返す手段がないからです。
最後に、amgetbitmap
は返されたタプルに関し、62.4に記載した意味でのロックを保証しません。
Note that it is permitted for an access method to implement only
<function>amgetbitmap</function> and not <function>amgettuple</function>, or vice versa,
if its internal implementation is unsuited to one API or the other.
アクセスメソッドの内部実装がどちらか片方のAPIにそぐわない場合、amgettuple
を実装せずamgetbitmap
のみを実装、またはその逆も許されていることに注意してください。