79633886

Date: 2025-05-22 13:47:19
Score: 1
Natty:
Report link

I am now building the query dynamically from the service based on the parameters. This causes the query to now use indices more often, but not yet in all cases. Here is the EXPLAIN ANALYZE of the new query:

Sort  (cost=19.00..19.00 rows=1 width=443) (actual time=0.037..0.038 rows=0 loops=1)
  Sort Key: ba.external_id
  Sort Method: quicksort  Memory: 25kB
  ->  Hash Right Join  (cost=6.23..18.99 rows=1 width=443) (actual time=0.021..0.022 rows=0 loops=1)
        Hash Cond: (process_cell.external_id = ba.process_cell_external_id)
        ->  Seq Scan on process_cell  (cost=0.00..12.00 rows=200 width=64) (never executed)
        ->  Hash  (cost=6.21..6.21 rows=1 width=411) (actual time=0.015..0.016 rows=0 loops=1)
              Buckets: 1024  Batches: 1  Memory Usage: 8kB
              ->  Index Scan using idx_ba_organization_id_external_id on business_asset ba  (cost=0.42..6.21 rows=1 width=411) (actual time=0.015..0.015 rows=0 loops=1)
                    Index Cond: (organization_id = '4970f599-44ab-4bab-aee4-455b995fd22b'::uuid)
"                    Filter: (((external_id ~~* concat('%', 'FA'::text, '%')) OR (description ~~* concat('%', 'FA'::text, '%')) OR (properties_yaml ~~* concat('%', 'FA'::text, '%'))) AND ((external_id ~~* concat('%', 'FF'::text, '%')) OR (description ~~* concat('%', 'FF'::text, '%')) OR (properties_yaml ~~* concat('%', 'FF'::text, '%'))))"
Planning Time: 1.388 ms
Execution Time: 0.071 ms

One example for the generated query is:

SELECT ba.*, process_cell.owners
        FROM business_asset ba
        LEFT JOIN process_cell
          ON ba.process_cell_external_id = process_cell.external_id
    
WHERE ba.organization_id = :organizationId
  AND (ba.external_id ILIKE CONCAT('%', replace(replace(:searchTerm0, '%', '\%'), '_', '\_'), '%') OR ba.description ILIKE CONCAT('%', replace(replace(:searchTerm0, '%', '\%'), '_', '\_'), '%') OR ba.properties_yaml ILIKE CONCAT('%', replace(replace(:searchTerm0, '%', '\%'), '_', '\_'), '%'))
  AND (ba.external_id ILIKE CONCAT('%', replace(replace(:searchTerm1, '%', '\%'), '_', '\_'), '%') OR ba.description ILIKE CONCAT('%', replace(replace(:searchTerm1, '%', '\%'), '_', '\_'), '%') OR ba.properties_yaml ILIKE CONCAT('%', replace(replace(:searchTerm1, '%', '\%'), '_', '\_'), '%'))
ORDER BY ba.external_id
LIMIT :pageSize OFFSET :offset;

As you can see it now only uses filters if the according parameters are set. Otherwise it now generated the lookups for the keywords instead of looping inside of the query.

From what I can see I still have to optimize the index usage on `process_cell`. I am happy to receive any feedback on my question and the result and what next steps would be useful. Also if I missinterpret something, please hit me up.

Reasons:
  • RegEx Blacklisted phrase (1): I missinterpret something, please
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: maistai