Skip to content

Commit 5e01f10

Browse files
committed
Fixes #27158: restore tag_usage prefix-LIKE index on Postgres
The 1.11.0 perf migration (#23054) added four `WHERE state = 1` partial indexes on tag_usage; #24063 dropped the matching `state = 1` predicate from getTagsInternalByPrefix (Suggested-state rows are valid for both classification and glossary derivation), leaving every partial index inapplicable. Postgres fell back to a parallel seq scan; MySQL was unaffected because its 1.11.0 indexes were never partial. Adds a non-partial single-col btree on targetfqnhash_lower (mirrors MySQL's idx_targetfqnhash_lower) and rebuilds the four partials as non-partial -- same shape, same INCLUDE columns, predicate coupling removed so future query changes can't silently invalidate them. Verified end-to-end against a local Postgres with 50k rows: seq scan reproduced before the fix (matches reporter's EXPLAIN), bitmap index scan after, both for inline and prepared-statement paths.
1 parent f52cafd commit 5e01f10

1 file changed

Lines changed: 27 additions & 0 deletions

File tree

bootstrap/sql/migrations/native/2.0.1/postgres/schemaChanges.sql

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,30 @@ CREATE TABLE IF NOT EXISTS task_migration_mapping (
1111

1212
CREATE INDEX IF NOT EXISTS idx_task_migration_mapping_new_task_id
1313
ON task_migration_mapping (new_task_id);
14+
15+
-- Issue #27158: tag_usage seq-scan on Postgres. #24063 dropped the
16+
-- `state = 1` predicate that 1.11.0's partial indexes required.
17+
-- Fix: add a single-col index, and drop the `WHERE state = 1` filter
18+
-- from the existing partials so query changes can't invalidate them.
19+
20+
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tag_usage_targetfqnhash_lower_pattern
21+
ON tag_usage (targetfqnhash_lower text_pattern_ops);
22+
23+
DROP INDEX CONCURRENTLY IF EXISTS idx_tag_usage_target_prefix_covering;
24+
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tag_usage_target_prefix_covering
25+
ON tag_usage (source, targetfqnhash_lower text_pattern_ops)
26+
INCLUDE (tagFQN, labelType, state);
27+
28+
DROP INDEX CONCURRENTLY IF EXISTS idx_tag_usage_tagfqn_prefix_covering;
29+
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tag_usage_tagfqn_prefix_covering
30+
ON tag_usage (source, tagfqn_lower text_pattern_ops)
31+
INCLUDE (targetFQNHash, labelType, state);
32+
33+
DROP INDEX CONCURRENTLY IF EXISTS idx_tag_usage_join_source;
34+
CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_tag_usage_join_source
35+
ON tag_usage (tagFQNHash, source)
36+
INCLUDE (targetFQNHash, tagFQN, labelType, state);
37+
38+
DROP INDEX CONCURRENTLY IF EXISTS gin_tag_usage_targetfqn_trgm;
39+
CREATE INDEX CONCURRENTLY IF NOT EXISTS gin_tag_usage_targetfqn_trgm
40+
ON tag_usage USING GIN (targetFQNHash gin_trgm_ops);

0 commit comments

Comments
 (0)