Skip to content

Commit 500a723

Browse files
extended PGVECTOR configurables
1 parent 493bd1a commit 500a723

File tree

4 files changed

+55
-13
lines changed

4 files changed

+55
-13
lines changed

engine/clients/pgvector/config.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@
55
PGVECTOR_USER = os.getenv("PGVECTOR_USER", "postgres")
66
PGVECTOR_PASSWORD = os.getenv("PGVECTOR_PASSWORD", "passwd")
77

8+
# Parallel execution settings
9+
PGVECTOR_MAX_PARALLEL_WORKERS_PER_GATHER = int(os.getenv("PGVECTOR_MAX_PARALLEL_WORKERS_PER_GATHER", 8))
10+
PGVECTOR_PARALLEL_TUPLE_COST = float(os.getenv("PGVECTOR_PARALLEL_TUPLE_COST", 0.01))
11+
PGVECTOR_PARALLEL_SETUP_COST = int(os.getenv("PGVECTOR_PARALLEL_SETUP_COST", 100))
12+
PGVECTOR_MIN_PARALLEL_TABLE_SCAN_SIZE = os.getenv("PGVECTOR_MIN_PARALLEL_TABLE_SCAN_SIZE", "1MB")
13+
PGVECTOR_FORCE_PARALLEL_MODE = os.getenv("PGVECTOR_FORCE_PARALLEL_MODE", "on")
14+
PGVECTOR_WORK_MEM = os.getenv("PGVECTOR_WORK_MEM", "4GB")
15+
816

917
def get_db_config(host, connection_params):
1018
return {

engine/clients/pgvector/search.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@
77

88
from engine.base_client.distances import Distance
99
from engine.base_client.search import BaseSearcher
10-
from engine.clients.pgvector.config import get_db_config
10+
from engine.clients.pgvector.config import (
11+
get_db_config,
12+
PGVECTOR_MAX_PARALLEL_WORKERS_PER_GATHER,
13+
PGVECTOR_PARALLEL_TUPLE_COST,
14+
PGVECTOR_PARALLEL_SETUP_COST,
15+
PGVECTOR_MIN_PARALLEL_TABLE_SCAN_SIZE,
16+
PGVECTOR_FORCE_PARALLEL_MODE,
17+
PGVECTOR_WORK_MEM,
18+
)
1119
from engine.clients.pgvector.parser import PgVectorConditionParser
1220

1321

@@ -26,10 +34,28 @@ def init_client(cls, host, distance, connection_params: dict, search_params: dic
2634
cls.distance = distance
2735
cls.search_params = search_params["search_params"]
2836

29-
# For FLAT searches, disable index usage to force full scan
37+
# For FLAT searches, optimize for parallel execution
3038
if "force_flat" in cls.search_params and cls.search_params["force_flat"]:
31-
cls.cur.execute("SET enable_indexscan = off")
32-
cls.cur.execute("SET enable_bitmapscan = off")
39+
# Note: We don't disable indexes globally since:
40+
# 1. No vector index exists in FLAT mode (not created)
41+
# 2. PostgreSQL will naturally do sequential scan for vector queries
42+
# 3. Other indexes (for filtering, etc.) remain useful
43+
44+
# Configurable parallel execution settings for FLAT searches
45+
# Priority: Environment variables (from config) > search_params > defaults
46+
parallel_workers = cls.search_params.get("max_parallel_workers_per_gather", PGVECTOR_MAX_PARALLEL_WORKERS_PER_GATHER)
47+
parallel_tuple_cost = cls.search_params.get("parallel_tuple_cost", PGVECTOR_PARALLEL_TUPLE_COST)
48+
parallel_setup_cost = cls.search_params.get("parallel_setup_cost", PGVECTOR_PARALLEL_SETUP_COST)
49+
min_parallel_size = cls.search_params.get("min_parallel_table_scan_size", PGVECTOR_MIN_PARALLEL_TABLE_SCAN_SIZE)
50+
force_parallel = cls.search_params.get("force_parallel_mode", PGVECTOR_FORCE_PARALLEL_MODE)
51+
work_mem = cls.search_params.get("work_mem", PGVECTOR_WORK_MEM)
52+
53+
cls.cur.execute(f"SET max_parallel_workers_per_gather = {parallel_workers}")
54+
cls.cur.execute(f"SET parallel_tuple_cost = {parallel_tuple_cost}")
55+
cls.cur.execute(f"SET parallel_setup_cost = {parallel_setup_cost}")
56+
cls.cur.execute(f"SET min_parallel_table_scan_size = '{min_parallel_size}'")
57+
cls.cur.execute(f"SET force_parallel_mode = {force_parallel}")
58+
cls.cur.execute(f"SET work_mem = '{work_mem}'")
3359

3460
@classmethod
3561
def search_one(cls, vector, meta_conditions, top) -> List[Tuple[int, float]]:
@@ -73,12 +99,5 @@ def search_one(cls, vector, meta_conditions, top) -> List[Tuple[int, float]]:
7399
@classmethod
74100
def delete_client(cls):
75101
if cls.cur:
76-
# Reset index settings if they were disabled for FLAT searches
77-
if "force_flat" in cls.search_params and cls.search_params["force_flat"]:
78-
try:
79-
cls.cur.execute("SET enable_indexscan = on")
80-
cls.cur.execute("SET enable_bitmapscan = on")
81-
except:
82-
pass # Connection might be closed already
83102
cls.cur.close()
84103
cls.conn.close()

engine/clients/pgvector/upload.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from pgvector.psycopg import register_vector
66

77
from engine.base_client.upload import BaseUploader
8-
from engine.clients.pgvector.config import get_db_config
8+
from engine.clients.pgvector.config import get_db_config, PGVECTOR_WORK_MEM
99

1010

1111
class PgvectorUploader(BaseUploader):
@@ -43,7 +43,7 @@ def init_client(cls, host, distance, connection_params, upload_params):
4343
max_maintenance_workers = 8
4444

4545
# Optimize memory settings for large uploads based on AWS recommendations
46-
cls.conn.execute("SET maintenance_work_mem = '2GB'")
46+
cls.conn.execute(f"SET maintenance_work_mem = '{PGVECTOR_WORK_MEM}'")
4747
cls.conn.execute(f"SET max_parallel_maintenance_workers = {max_maintenance_workers}")
4848

4949
@classmethod

experiments/configurations/pgvector-single-node.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,20 @@
120120
{ "parallel": 100, "search_params": { "force_flat": true } }
121121
],
122122
"upload_params": { "parallel": 16 }
123+
},
124+
{
125+
"name": "pgvector-flat-high-perf",
126+
"engine": "pgvector",
127+
"connection_params": {},
128+
"collection_params": {
129+
"flat_config": {
130+
"create_index": false,
131+
"max_parallel_workers": "auto"
132+
}
133+
},
134+
"search_params": [
135+
{ "parallel": 1, "search_params": { "force_flat": true } }
136+
],
137+
"upload_params": { "parallel": 16 }
123138
}
124139
]

0 commit comments

Comments
 (0)