mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-10-12 08:02:44 +00:00
perf: index agent paths so the merged listing and owner counts skip other resources
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Vo7HXMdgqXJhR7p8YyVgjB
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
837358e962
commit
5e674cdfb9
@@ -0,0 +1 @@
|
||||
DROP INDEX IF EXISTS idx_resource_agent_owner_prefix;
|
||||
@@ -0,0 +1,7 @@
|
||||
-- Backs the agent branch of /runnables/list and /runnables/counts, which reach the
|
||||
-- `ai_agent` rows of `resource` by workspace and byte-ordered path prefix. Partial, so
|
||||
-- neither walks the workspace's other resources (state, cache, ...).
|
||||
-- Created CONCURRENTLY via the OVERRIDDEN_MIGRATIONS rewrite in windmill-api/src/db.rs.
|
||||
CREATE INDEX IF NOT EXISTS idx_resource_agent_owner_prefix
|
||||
ON resource (workspace_id, path text_pattern_ops)
|
||||
WHERE resource_type = 'ai_agent';
|
||||
@@ -111,6 +111,9 @@ lazy_static::lazy_static! {
|
||||
(20260909163047, include_str!(
|
||||
"../../migrations/20260909163047_workspace_delete_cascade_indexes.up.sql"
|
||||
).replace("CREATE INDEX", "CREATE INDEX CONCURRENTLY").replace("DROP INDEX", "DROP INDEX CONCURRENTLY")),
|
||||
(20261009173546, include_str!(
|
||||
"../../migrations/20261009173546_agent_owner_prefix_index.up.sql"
|
||||
).replace("CREATE INDEX", "CREATE INDEX CONCURRENTLY")),
|
||||
].into_iter().collect();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
//! Efficiency: each kind is a UNION ALL branch ordered by an index on
|
||||
//! `(workspace_id, archived, <sort key>)` (created_at / edited_at, or the lowered
|
||||
//! summary-or-path expression for name orders); Postgres merges the ordered
|
||||
//! branches and stops at the page limit. Pagination is keyset — a
|
||||
//! branches and stops at the page limit. Agents, which are few, are instead
|
||||
//! reached through the partial `idx_resource_agent_owner_prefix` and sorted whole. Pagination is keyset — a
|
||||
//! `(sort_key, path, kind, tiebreak)` cursor, where `tiebreak` (a script's hash,
|
||||
//! 0 for flow/app) is a stable final key that keeps the order total even when rows
|
||||
//! tie on (sort_key, path, kind) — so deep pages don't re-scan. Visibility is
|
||||
@@ -858,7 +859,7 @@ struct OwnerCount {
|
||||
/// `owner/<rest>` is >= `owner || '/'` and, since '/' (0x2F) is immediately
|
||||
/// followed by '0' (0x30), < `owner || '0'`. `~>=~` / `~<~` are the
|
||||
/// text_pattern_ops operators, which is what lets `idx_<kind>_owner_prefix`
|
||||
/// answer the count with an index-only scan — the default opclass sorts by the
|
||||
/// (`idx_resource_agent_owner_prefix` for agents) answer the count with an index-only scan — the default opclass sorts by the
|
||||
/// database collation and cannot serve a byte-prefix range.
|
||||
fn owner_prefix_range(alias: &str) -> String {
|
||||
format!("{alias}.path ~>=~ (o.owner || '/') AND {alias}.path ~<~ (o.owner || '0')")
|
||||
|
||||
Reference in New Issue
Block a user