mirror of
https://github.com/netbox-community/netbox.git
synced 2025-08-28 10:16:10 -06:00
Fixes #20023: Add GiST index on Prefix.prefix for net contains ops (#20059)
Some checks failed
CodeQL / Analyze (${{ matrix.language }}) (none, actions) (push) Waiting to run
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Waiting to run
CodeQL / Analyze (${{ matrix.language }}) (none, python) (push) Waiting to run
CI / build (20.x, 3.10) (push) Has been cancelled
CI / build (20.x, 3.11) (push) Has been cancelled
CI / build (20.x, 3.12) (push) Has been cancelled
Some checks failed
CodeQL / Analyze (${{ matrix.language }}) (none, actions) (push) Waiting to run
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Waiting to run
CodeQL / Analyze (${{ matrix.language }}) (none, python) (push) Waiting to run
CI / build (20.x, 3.10) (push) Has been cancelled
CI / build (20.x, 3.11) (push) Has been cancelled
CI / build (20.x, 3.12) (push) Has been cancelled
Resolves performance issue where prefix deletion with 2000+ children took 5-10 minutes due to sequential scans in hierarchy depth/children calculations. Adding PostgreSQL GiST index with inet_ops enables efficient network containment operators (>>, <<, <<=) in annotate_hierarchy() queries. Performance impact: - 30-60x speedup: 5-10 minutes → 10 seconds for large prefix deletions - Real-world validation: 4s migration time on 1.24M prefix dataset - Storage cost: 47MB index (11% of table storage, 38 bytes per prefix) Works in conjunction with existing B-tree indexes on vrf_id for optimal query performance. Benefits all network containment operations including hierarchy navigation, aggregate views, and available IP/prefix calculations.
This commit is contained in:
parent
5d7c8318aa
commit
8bb47dad0f
@ -0,0 +1,20 @@
|
|||||||
|
from django.contrib.postgres.indexes import GistIndex
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('contenttypes', '0002_remove_content_type_name'),
|
||||||
|
('dcim', '0210_macaddress_ordering'),
|
||||||
|
('extras', '0129_fix_script_paths'),
|
||||||
|
('ipam', '0081_remove_service_device_virtual_machine_add_parent_gfk_index'),
|
||||||
|
('tenancy', '0020_remove_contactgroupmembership'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddIndex(
|
||||||
|
model_name='prefix',
|
||||||
|
index=GistIndex(fields=['prefix'], name='ipam_prefix_gist_idx', opclasses=['inet_ops']),
|
||||||
|
),
|
||||||
|
]
|
@ -1,5 +1,6 @@
|
|||||||
import netaddr
|
import netaddr
|
||||||
from django.contrib.contenttypes.fields import GenericForeignKey
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
||||||
|
from django.contrib.postgres.indexes import GistIndex
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.db.models import F
|
from django.db.models import F
|
||||||
@ -281,6 +282,13 @@ class Prefix(ContactsMixin, GetAvailablePrefixesMixin, CachedScopeMixin, Primary
|
|||||||
ordering = (F('vrf').asc(nulls_first=True), 'prefix', 'pk') # (vrf, prefix) may be non-unique
|
ordering = (F('vrf').asc(nulls_first=True), 'prefix', 'pk') # (vrf, prefix) may be non-unique
|
||||||
verbose_name = _('prefix')
|
verbose_name = _('prefix')
|
||||||
verbose_name_plural = _('prefixes')
|
verbose_name_plural = _('prefixes')
|
||||||
|
indexes = [
|
||||||
|
GistIndex(
|
||||||
|
fields=['prefix'],
|
||||||
|
name='ipam_prefix_gist_idx',
|
||||||
|
opclasses=['inet_ops'],
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
Loading…
Reference in New Issue
Block a user