We’re in the process of testing a transition from using fixtures to manage a hierarchy of districts and health posts, towards using cases. Functionally, everything seems to be working great. However, I wonder if we need to consider any performance implications. Our ‘district’ fixture contains about 20 items, while our ‘health post’ fixture contains 600+ items. After implementing these as cases (with health post cases linked to their parent district cases), there is an initial download of 600+ cases to the phone during a sync.
[Note: at this point the fixtures are still on the phone too, but they will be removed once everything is confirmed to be working fine]
Things seem be performing fine on my phone, but it’s a very capable phone compared to what most users have. So, I worry that the additional 600+ cases may introduce an unexpected performance hit once deployed.
[e.g. are fixtures ‘more efficient’ then case lists]
Cases are stored on the phone in a hybrid database/document format that can store tens or hundreds of thousands of rows (although performing queries against those db sizes is harder to optimize). Performance is affected by many factors, but I can say outright that 600 cases is not a large number for most situations.
A few general things to keep in mind:
- queries for individual cases (IE: casedb/case[@case_id = /data/reference]) should almost always be constant time, regardless of the db size
- if you are performing a query against multiple cases, putting a filter for the case type first, and on its own (ie: casedb/case[@case_type = ‘health_post’]) will isolate any remaining filters to run against the scope of that case type only, not against all cases, regardless of how many cases are on-device.
- If the casedb is large, be careful to avoid queries which bundle together the first predicate with AND,
- IE: casedb/case[@case_type = ‘health_post’ and size=‘small’].
- Instead you should use multiple predicates for this purpose and ensure that the first predicate is isolated
- IE: casedb/case[@case_type = ‘health_post’][size=‘small’]
- This is because the engine applies static analysis to the predicates to index queries which can be done raw in SQL
- be cautious about nested queries (IE: casedb/case[myproperty = casedb/case[something_else…]), often pulling out the inner query and storing it in a form hidden value can prevent related performance issues.
Thanks Clayton. We’ll definitely implement our case filtering accordingly. Ray