Joining might not always be the best solution. If a table contains too
much data, and you later run sorting on top of it, it will be slow.
In this case, we will first reduce the instances table to a minimal
version because instances usually share the same SDK versions. Only
after that, we join.
Based on some customer data, we reduced query time from 3000ms to 60ms.
However, this will vary based on the number of instances the customer
has.
This escape with `??` double escaped the LIKE query causing no results.
This updates to using whereLike, which does the correct escaping for
string query.
Only triggers if there is any rows in client instances that have
sdk_version: unleash-edge with version < 17.0.0
The function that checks this memoizes the check for 10 minutes to avoid
scanning the client instances table too often.
## About the changes
This metric will expose an aggregated view of how many client
applications are registered in Unleash. Since applications are ephemeral
we are exposing this metric in different time windows based on when the
application was last seen.
The caveat is that we issue a database query for each new range we want
to add. Hopefully, this should not be a problem because:
a) the amount of ranges we'd expose is small and unlikely to grow
b) this is currently updated at startup time and even if we update it on
a scheduled basis the refresh rate will be rather sparse
## Sample data
This is how metrics will look like
```
# HELP client_apps_total Number of registered client apps aggregated by range by last seen
# TYPE client_apps_total gauge
client_apps_total{range="allTime"} 3
client_apps_total{range="30d"} 3
client_apps_total{range="7d"} 2
```