-
I think the issue you’re encountering is due to the nature of regular expressions (~) in PostgreSQL queries, which are inherently slower compared to direct comparisons because regular expressions require a full scan or sequential scan of the JSONB structure, while equality operations can use indexes effectively. In your query using the regex, most of the time is spent in the sequential scan on the factsets table:
actual time=14.447..5033.863 ms
Regular expressions can be accelerated by using GIN or GiST indexes on JSONB fields. You can create a GIN index on your stable and volatile fields using the jsonb_path_ops or a custom expression to improve query speed. For example, a combined index on the stable and volatile fields:
CREATE INDEX idx_factsets_hostgroup ON factsets USING GIN ((stable || volatile) jsonb_path_ops);
or:
CREATE INDEX idx_factsets_hostgroup ON factsets USING GIN ((stable || volatile) -> 'hostgroup');
could help accelerating queries that use ~ or other search-related functions.
The first of these two indexes uses the jsonb_path_ops operator class, which is specialized for indexing paths (keys) within JSONB data, and will index all keys and their presence in the combined result of (stable || volatile), what makes it ideal for existence checks (? operator).
The second one targets a specific key (hostgroup) within the combined JSONB structure (stable || volatile), and it will index the values stored under the hostgroup key, making it suitable for value-based searches (e.g., =, @>, ? operators) on that specific key rather than on the entire JSONB structure.
Alternatively, if you are querying a limited set of host groups often, you could create a partial index for those values. For instance, this index would only be used for queries involving the specified regular expression with 'lxplus', reducing the overall index size and improving query performance:
CREATE INDEX idx_factsets_hostgroup_partial ON factsets USING GIN ((stable || volatile) jsonb_path_ops) WHERE (stable || volatile) ->> 'hostgroup' ~ 'lxplus';
You may want to try something like that and see if things improve.
Please register or sign in to comment