-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Description
NetBox version
v3.4.2
Feature type
Change to existing functionality
Proposed functionality
Create a functional index on the ipam.ip_address table. Which indexes the output of CAST(HOST(ipam.ipaddress)) so it isn't called on every execution of the query - which can be computationally expensive.
Use case
I've detailed my findings in this discussion thread.
Queries/searches for IPAddress filtered by parent Prefixes can be CPU intensive to the database and, depending on the parent prefix and IP addresses present, can be very inefficient when searching through hundreds of thousands of IPs (~260K) and only returning a few. Query time itself isn't terrible, but there is a noticeable uptick in CPU & DB worker threads/processes generated by this type of query compared to others - and that can be of concern to larger/high-volume instances.
The culprit is mostly with calling CAST(HOST("ipam_ipaddress"."address") AS INET)
Line 154 in d7c37d9
| return 'CAST(HOST(%s) AS INET) <<= %s' % (lhs, rhs), params |
address with btree or inet_ops makes little difference in performance and query cost.
But the above functional index is 1/3 the query cost (2264 vs 6632) and the query time is <=2ms (vs ~70ms). I observed a ~5MB increase (+8%) in table disk size (260K IPs) with this index, and new data insertion time seemed un-impacted in any noticeable way (Using the REST API: (0.0185s without index, 0.0166s with index)).
Additional metrics
Querying the /ipam/ip-addresses/ endpoint ~2K times with different prefixes as parent and 3 separate client processes:
- No index:
6m18s - With index:
4m37s
Database changes
New index on address field.
CREATE INDEX ipam_ipaddress_address_host_idx ON ipam_ipaddress (cast(host(address) as inet));One possible way is in a manually-defined migrations file:
operations = [
migrations.RunSQL(
sql="CREATE INDEX ipam_ipaddress_address_host_idx ON ipam_ipaddress (cast(host(address) as inet))",
reverse_sql='DROP INDEX ipam_ipaddress_address_host_idx ON ipam_ipaddress'
)
]or it might be possible on the model itself via defining an index expression.
External dependencies
N/A
And thanks & credit to @candlerb & @kkthxbye-code for setting me down the path