Skip to content

Commit ac6576e

Browse files
committed
Added hnsw.search_mem_multiplier option
1 parent 67eff41 commit ac6576e

File tree

4 files changed

+15
-6
lines changed

4 files changed

+15
-6
lines changed

src/hnsw.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ static const struct config_enum_entry hnsw_iterative_search_options[] = {
2828
int hnsw_ef_search;
2929
int hnsw_iterative_search;
3030
int hnsw_max_search_tuples;
31+
double hnsw_search_mem_multiplier;
3132
int hnsw_lock_tranche_id;
3233
static relopt_kind hnsw_relopt_kind;
3334

@@ -87,6 +88,11 @@ HnswInit(void)
8788
NULL, &hnsw_max_search_tuples,
8889
20000, 1, INT_MAX, PGC_USERSET, 0, NULL, NULL, NULL);
8990

91+
/* Same range and default as hash_mem_multiplier */
92+
DefineCustomRealVariable("hnsw.search_mem_multiplier", "Sets the multiple of work_mem to use for iterative search",
93+
NULL, &hnsw_search_mem_multiplier,
94+
2, 1, 1000, PGC_USERSET, 0, NULL, NULL, NULL);
95+
9096
MarkGUCPrefixReserved("hnsw");
9197
}
9298

src/hnsw.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
extern int hnsw_ef_search;
112112
extern int hnsw_iterative_search;
113113
extern int hnsw_max_search_tuples;
114+
extern double hnsw_search_mem_multiplier;
114115
extern int hnsw_lock_tranche_id;
115116

116117
typedef enum HnswIterativeSearchMode
@@ -372,6 +373,7 @@ typedef struct HnswScanOpaqueData
372373
int m;
373374
int64 tuples;
374375
double previousDistance;
376+
Size maxMemory;
375377
MemoryContext tmpCtx;
376378

377379
/* Support functions */

src/hnswscan.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,8 @@ hnswbeginscan(Relation index, int nkeys, int norderbys)
138138
/* Set support functions */
139139
HnswInitSupport(&so->support, index);
140140

141+
so->maxMemory = (Size) (work_mem * 1024.0 * hnsw_search_mem_multiplier);
142+
141143
scan->opaque = so;
142144

143145
return scan;
@@ -244,13 +246,13 @@ hnswgettuple(IndexScanDesc scan, ScanDirection dir)
244246
so->w = lappend(so->w, HnswGetSearchCandidate(w_node, pairingheap_remove_first(so->discarded)));
245247
}
246248
/* Prevent scans from consuming too much memory */
247-
else if (MemoryContextMemAllocated(so->tmpCtx, false) > (Size) work_mem * 1024L)
249+
else if (MemoryContextMemAllocated(so->tmpCtx, false) >= so->maxMemory)
248250
{
249251
if (pairingheap_is_empty(so->discarded))
250252
{
251253
ereport(DEBUG1,
252-
(errmsg("hnsw index scan exceeded work_mem after " INT64_FORMAT " tuples", so->tuples),
253-
errhint("Increase work_mem to scan more tuples.")));
254+
(errmsg("hnsw index scan reached memory limit after " INT64_FORMAT " tuples", so->tuples),
255+
errhint("Increase hnsw.search_mem_multiplier to scan more tuples.")));
254256

255257
break;
256258
}

test/t/043_hnsw_iterative_search.pl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
SET enable_seqscan = off;
2929
SET hnsw.iterative_search = relaxed_order;
3030
SET hnsw.max_search_tuples = 100000;
31-
SET work_mem = '8MB';
3231
SELECT COUNT(*) FROM (SELECT v FROM tst WHERE i % 10000 = 0 ORDER BY v <-> (SELECT v FROM tst LIMIT 1) LIMIT 11) t;
3332
));
3433
is($count, 10);
@@ -45,7 +44,6 @@
4544
SET enable_seqscan = off;
4645
SET hnsw.iterative_search = relaxed_order;
4746
SET hnsw.max_search_tuples = $max_tuples;
48-
SET work_mem = '8MB';
4947
SELECT COUNT(*) FROM (SELECT v FROM tst WHERE i % 10000 = 0 ORDER BY v <-> (SELECT v FROM tst WHERE i = $i) LIMIT 11) t;
5048
));
5149
$sum += $count;
@@ -61,8 +59,9 @@
6159
SET hnsw.iterative_search = relaxed_order;
6260
SET client_min_messages = debug1;
6361
SET work_mem = '1MB';
62+
SET hnsw.search_mem_multiplier = 1;
6463
SELECT COUNT(*) FROM (SELECT v FROM tst WHERE i % 10000 = 0 ORDER BY v <-> (SELECT v FROM tst LIMIT 1) LIMIT 11) t;
6564
));
66-
like($stderr, qr/hnsw index scan exceeded work_mem after \d+ tuples/);
65+
like($stderr, qr/hnsw index scan reached memory limit after \d+ tuples/);
6766

6867
done_testing();

0 commit comments

Comments
 (0)