7
7
8
8
from engine .base_client .distances import Distance
9
9
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
+ )
11
19
from engine .clients .pgvector .parser import PgVectorConditionParser
12
20
13
21
@@ -26,10 +34,28 @@ def init_client(cls, host, distance, connection_params: dict, search_params: dic
26
34
cls .distance = distance
27
35
cls .search_params = search_params ["search_params" ]
28
36
29
- # For FLAT searches, disable index usage to force full scan
37
+ # For FLAT searches, optimize for parallel execution
30
38
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 } '" )
33
59
34
60
@classmethod
35
61
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]]:
73
99
@classmethod
74
100
def delete_client (cls ):
75
101
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
83
102
cls .cur .close ()
84
103
cls .conn .close ()
0 commit comments