Skip to content

Commit

Permalink
Update alert group search to force index in MySQL (#4731)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
matiasb authored Jul 25, 2024
1 parent 1a6d778 commit 845940d
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 5 deletions.
7 changes: 4 additions & 3 deletions engine/apps/api/views/alert_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,9 +335,10 @@ def get_queryset(self, ignore_filtering_by_available_teams=False):
if settings.ALERT_GROUPS_DISABLE_PREFER_ORDERING_INDEX:
# workaround related to MySQL "ORDER BY LIMIT Query Optimizer Bug"
# read more: https://hackmysql.com/infamous-order-by-limit-query-optimizer-bug/
# this achieves the same effect as "FORCE INDEX (alert_group_list_index)" when
# paired with "ORDER BY started_at_optimized DESC" (ordering is performed in AlertGroupCursorPaginator).
queryset = queryset.extra({"started_at_optimized": "alerts_alertgroup.started_at + 0"})
from django_mysql.models import add_QuerySetMixin

queryset = add_QuerySetMixin(queryset)
queryset = queryset.force_index("alert_group_list_index")

# Filter by labels. Since alert group labels are "static" filter by names, not IDs.
label_query = self.request.query_params.getlist("label", [])
Expand Down
3 changes: 1 addition & 2 deletions engine/common/api_helpers/paginators.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import typing

from django.conf import settings
from rest_framework.pagination import BasePagination, CursorPagination, PageNumberPagination
from rest_framework.response import Response

Expand Down Expand Up @@ -86,4 +85,4 @@ class FifteenPageSizePaginator(PathPrefixedPagePagination):

class AlertGroupCursorPaginator(PathPrefixedCursorPagination):
page_size = 25
ordering = "-started_at_optimized" if settings.ALERT_GROUPS_DISABLE_PREFER_ORDERING_INDEX else "-started_at"
ordering = "-started_at"
5 changes: 5 additions & 0 deletions engine/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ class DatabaseTypes:

pymysql.install_as_MySQLdb()

DJANGO_MYSQL_REWRITE_QUERIES = True

ALERT_GROUPS_DISABLE_PREFER_ORDERING_INDEX = DATABASE_TYPE == DatabaseTypes.MYSQL and getenv_boolean(
"ALERT_GROUPS_DISABLE_PREFER_ORDERING_INDEX", default=False
)
Expand Down Expand Up @@ -293,6 +295,9 @@ class DatabaseTypes:
"apps.chatops_proxy",
]

if DATABASE_TYPE == DatabaseTypes.MYSQL:
INSTALLED_APPS += ["django_mysql"]

REST_FRAMEWORK = {
"DEFAULT_PARSER_CLASSES": (
"rest_framework.parsers.JSONParser",
Expand Down

0 comments on commit 845940d

Please sign in to comment.