Skip to content

Commit 845940d

Browse files
authored
Update alert group search to force index in MySQL (#4731)
Related to grafana/oncall-private#2679 Confirmed the query rewriting works via MySQL query logs (index is also forced for the stats queries): `2024-07-24T19:50:59.482751Z 3977 Query SELECT `alerts_alertgroup`.`id` FROM `alerts_alertgroup` FORCE INDEX (`alert_group_list_index`) WHERE (`alerts_alertgroup`.`channel_id` IN (13) AND (1) AND (`alerts_alertgroup`.`public_primary_key` LIKE 'test' OR `alerts_alertgroup`.`inside_organization_number` LIKE 'test' OR `alerts_alertgroup`.`web_title_cache` LIKE '%test%') AND `alerts_alertgroup`.`root_alert_group_id` IS NULL AND ((`alerts_alertgroup`.`silenced` = ('0') AND `alerts_alertgroup`.`acknowledged` = ('0') AND `alerts_alertgroup`.`resolved` = ('0')) OR (`alerts_alertgroup`.`acknowledged` = ('1') AND `alerts_alertgroup`.`resolved` = ('0'))) AND `alerts_alertgroup`.`started_at` >= '2024-06-24 19:50:58' AND `alerts_alertgroup`.`started_at` <= '2024-07-24 19:50:58') ORDER BY `alerts_alertgroup`.`started_at` DESC LIMIT 26 ` Rewriting will only be applied to the alert group search queries, when the feature flags are enabled. Dependency was already listed as a requirement.
1 parent 1a6d778 commit 845940d

File tree

3 files changed

+10
-5
lines changed

3 files changed

+10
-5
lines changed

engine/apps/api/views/alert_group.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,10 @@ def get_queryset(self, ignore_filtering_by_available_teams=False):
335335
if settings.ALERT_GROUPS_DISABLE_PREFER_ORDERING_INDEX:
336336
# workaround related to MySQL "ORDER BY LIMIT Query Optimizer Bug"
337337
# read more: https://hackmysql.com/infamous-order-by-limit-query-optimizer-bug/
338-
# this achieves the same effect as "FORCE INDEX (alert_group_list_index)" when
339-
# paired with "ORDER BY started_at_optimized DESC" (ordering is performed in AlertGroupCursorPaginator).
340-
queryset = queryset.extra({"started_at_optimized": "alerts_alertgroup.started_at + 0"})
338+
from django_mysql.models import add_QuerySetMixin
339+
340+
queryset = add_QuerySetMixin(queryset)
341+
queryset = queryset.force_index("alert_group_list_index")
341342

342343
# Filter by labels. Since alert group labels are "static" filter by names, not IDs.
343344
label_query = self.request.query_params.getlist("label", [])

engine/common/api_helpers/paginators.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import typing
22

3-
from django.conf import settings
43
from rest_framework.pagination import BasePagination, CursorPagination, PageNumberPagination
54
from rest_framework.response import Response
65

@@ -86,4 +85,4 @@ class FifteenPageSizePaginator(PathPrefixedPagePagination):
8685

8786
class AlertGroupCursorPaginator(PathPrefixedCursorPagination):
8887
page_size = 25
89-
ordering = "-started_at_optimized" if settings.ALERT_GROUPS_DISABLE_PREFER_ORDERING_INDEX else "-started_at"
88+
ordering = "-started_at"

engine/settings/base.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,8 @@ class DatabaseTypes:
189189

190190
pymysql.install_as_MySQLdb()
191191

192+
DJANGO_MYSQL_REWRITE_QUERIES = True
193+
192194
ALERT_GROUPS_DISABLE_PREFER_ORDERING_INDEX = DATABASE_TYPE == DatabaseTypes.MYSQL and getenv_boolean(
193195
"ALERT_GROUPS_DISABLE_PREFER_ORDERING_INDEX", default=False
194196
)
@@ -293,6 +295,9 @@ class DatabaseTypes:
293295
"apps.chatops_proxy",
294296
]
295297

298+
if DATABASE_TYPE == DatabaseTypes.MYSQL:
299+
INSTALLED_APPS += ["django_mysql"]
300+
296301
REST_FRAMEWORK = {
297302
"DEFAULT_PARSER_CLASSES": (
298303
"rest_framework.parsers.JSONParser",

0 commit comments

Comments
 (0)