pub enum HnswIterativeScan {
Off,
RelaxedOrder,
StrictOrder,
}Expand description
How pgvector’s HNSW index behaves when a filter eliminates the candidates it handed up (#1116).
With pgvector’s own default — off — an HNSW scan produces one bounded
candidate list and the filter is applied to it. Once the filter is selective
the list is exhausted before k survivors exist, and the query succeeds
with fewer rows: measured at 100 000 documents, k = 10 and a 1%-selective
filter, three rows and a recall of 0.20, with nothing to distinguish that
from “only three matched”. That is why FraiseQL names a value here instead
of inheriting the server’s.
⚠ An invalid value is not an error. pgvector’s GUC is defined when its
library loads, after the startup packet has been accepted, so a bad value
produces WARNING: invalid value for parameter "hnsw.iterative_scan" and
silently falls back to off — the failure this setting exists to prevent.
Being an enum is what keeps an unrepresentable value from reaching the wire.
Variants§
Off
pgvector’s own default: one bounded candidate list, no continuation.
Filtered searches may silently return fewer than k rows.
RelaxedOrder
Continue scanning until k rows survive the filter, without buffering
for exact ordering. Results may be slightly out of distance order.
StrictOrder
Continue scanning until k rows survive, preserving exact distance
order.
The default, and the reason is the contract rather than the benchmark:
nearest is documented to return rows most-similar-first, and a plan
whose ordering comes from the index scan can only honour that if the
scan is ordered. relaxed_order would trade #1116’s silent
under-return for a quieter version of the same thing — a result that
looks right and is subtly not.
The benchmark in benches/vector_filtered_ann.sql found the two
indistinguishable in both recall and latency, so the guarantee is the
only thing separating them there. An operator whose corpus disagrees can
say so.
Implementations§
Source§impl HnswIterativeScan
impl HnswIterativeScan
Sourcepub const fn as_guc_value(self) -> &'static str
pub const fn as_guc_value(self) -> &'static str
The value as pgvector spells it.
Trait Implementations§
Source§impl Clone for HnswIterativeScan
impl Clone for HnswIterativeScan
Source§fn clone(&self) -> HnswIterativeScan
fn clone(&self) -> HnswIterativeScan
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for HnswIterativeScan
Source§impl Debug for HnswIterativeScan
impl Debug for HnswIterativeScan
Source§impl Default for HnswIterativeScan
impl Default for HnswIterativeScan
Source§fn default() -> HnswIterativeScan
fn default() -> HnswIterativeScan
Source§impl<'de> Deserialize<'de> for HnswIterativeScan
impl<'de> Deserialize<'de> for HnswIterativeScan
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<HnswIterativeScan, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<HnswIterativeScan, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
impl Eq for HnswIterativeScan
Source§impl PartialEq for HnswIterativeScan
impl PartialEq for HnswIterativeScan
Source§impl Serialize for HnswIterativeScan
impl Serialize for HnswIterativeScan
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
impl StructuralPartialEq for HnswIterativeScan
Auto Trait Implementations§
impl Freeze for HnswIterativeScan
impl RefUnwindSafe for HnswIterativeScan
impl Send for HnswIterativeScan
impl Sync for HnswIterativeScan
impl Unpin for HnswIterativeScan
impl UnsafeUnpin for HnswIterativeScan
impl UnwindSafe for HnswIterativeScan
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> DeserializeOwned for Twhere
T: for<'de> Deserialize<'de>,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.