From e387b9608def957fd59618d548e1dba03d37275e Mon Sep 17 00:00:00 2001
From: Rodolfo Alonso Hernandez <ralonsoh@redhat.com>
Date: Thu, 19 Sep 2024 14:00:57 +0000
Subject: [PATCH] Change the load method of SG rule "default_security_group"

Since [1], the SG rule SQL view also retrieves the table
"default_security_group", using a complex relationship [2].
When the number of SG rules of a SG is high (above 50 it
is clearly noticeable the performance degradation), the
API call can take several seconds. For example, for 100
SG rules it can take up to one minute.

This patch changes the load method of the SG rule
"default_security_group" relationship to "selectin".
Benchmarks with a single default SG and 100 rules,
doing "openstack security group show $sg":
* 2023.2 (without this feature): around 0.05 seconds
* master: between 45-50 seconds (1000x time increase)
* loading method "selectin" or "dynamic": around 0.5 seconds.

NOTE: this feature [1] was implemented in 2024.1. At this
time, SQLAlchemy version was <2.0 and "selectin" method was
not available. For this version, "dynamic" can be used instead.

[1]https://review.opendev.org/q/topic:%22bug/2019960%22
[2]https://github.com/openstack/neutron/blob/08fff4087dc342be40db179fca0cd9bbded91053/neutron/db/models/securitygroup.py#L120-L121

Closes-Bug: #2081087
Change-Id: I46af1179f6905307c0d60b5c0fdee264a40a4eac
(cherry picked from commit c1b05e29adf9d0d68c1ac636013a8a363a92eb85)
---
 neutron/db/models/securitygroup.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/neutron/db/models/securitygroup.py b/neutron/db/models/securitygroup.py
index 86e0e746444..cf9b103ed25 100644
--- a/neutron/db/models/securitygroup.py
+++ b/neutron/db/models/securitygroup.py
@@ -115,7 +115,7 @@ class DefaultSecurityGroup(model_base.BASEV2, model_base.HasProjectPrimaryKey):
         primaryjoin="SecurityGroup.id==DefaultSecurityGroup.security_group_id",
     )
     security_group_rule = orm.relationship(
-        SecurityGroupRule, lazy='joined',
+        SecurityGroupRule, lazy='selectin',
         backref=orm.backref('default_security_group'),
         primaryjoin="foreign(SecurityGroupRule.security_group_id) == "
                     "DefaultSecurityGroup.security_group_id",