Skip to content

Commit aac9812

Browse files
authored
perf: batch fetch filter functions to eliminate N+1 queries (open-webui#21018)
1 parent 44e36e5 commit aac9812

3 files changed

Lines changed: 24 additions & 12 deletions

File tree

backend/open_webui/models/functions.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,26 @@ def get_function_by_id(
195195
except Exception:
196196
return None
197197

198+
def get_functions_by_ids(
199+
self, ids: list[str], db: Optional[Session] = None
200+
) -> list[FunctionModel]:
201+
"""
202+
Batch fetch multiple functions by their IDs in a single query.
203+
Returns functions in the same order as the input IDs (None entries filtered out).
204+
"""
205+
if not ids:
206+
return []
207+
try:
208+
with get_db_context(db) as db:
209+
functions = db.query(Function).filter(Function.id.in_(ids)).all()
210+
# Create a dict for O(1) lookup
211+
func_dict = {f.id: FunctionModel.model_validate(f) for f in functions}
212+
# Return in original order, filtering out any not found
213+
return [func_dict[id] for id in ids if id in func_dict]
214+
except Exception:
215+
return []
216+
217+
198218
def get_functions(
199219
self, active_only=False, include_valves=False, db: Optional[Session] = None
200220
) -> list[FunctionModel | FunctionWithValvesModel]:

backend/open_webui/utils/chat.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -341,12 +341,8 @@ async def chat_completed(request: Request, form_data: dict, user: Any):
341341
}
342342

343343
try:
344-
filter_functions = [
345-
Functions.get_function_by_id(filter_id)
346-
for filter_id in get_sorted_filter_ids(
347-
request, model, metadata.get("filter_ids", [])
348-
)
349-
]
344+
filter_ids = get_sorted_filter_ids(request, model, metadata.get("filter_ids", []))
345+
filter_functions = Functions.get_functions_by_ids(filter_ids)
350346

351347
result, _ = await process_filter_functions(
352348
request=request,

backend/open_webui/utils/middleware.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,12 +1570,8 @@ async def process_chat_payload(request, form_data, user, metadata, model):
15701570
raise e
15711571

15721572
try:
1573-
filter_functions = [
1574-
Functions.get_function_by_id(filter_id)
1575-
for filter_id in get_sorted_filter_ids(
1576-
request, model, metadata.get("filter_ids", [])
1577-
)
1578-
]
1573+
filter_ids = get_sorted_filter_ids(request, model, metadata.get("filter_ids", []))
1574+
filter_functions = Functions.get_functions_by_ids(filter_ids)
15791575

15801576
form_data, flags = await process_filter_functions(
15811577
request=request,

0 commit comments

Comments
 (0)