We had an exception today caused by a slow running query.

This PR will optimize this query to use a more efficient index.

- Add notification_type to the dao_get_last_template_usage to optimize the query.
- Tested and analyzed query on production database with very significant results.
 Before:
                                                                                 QUERY PLAN
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.43..1711.35 rows=1 width=935) (actual time=21186.053..21186.053 rows=0 loops=1)
   ->  Index Scan Backward using ix_notifications_created_at on notifications  (cost=0.43..4607493.80 rows=2693 width=935) (actual time=21186.052..21186.052 rows=0 loops=1)
         Filter: (((key_type)::text <> 'test'::text) AND (template_id = 'xxxxxx'::uuid))
         Rows Removed by Filter: 8244071
 Planning time: 0.112 ms
 Execution time: 21186.082 ms
 After:
                                                     QUERY PLAN
---------------------------------------------------------------------------------------------------------------------
 Limit  (cost=5323.10..5323.10 rows=1 width=935)
   ->  Sort  (cost=5323.10..5323.74 rows=258 width=935)
         Sort Key: created_at DESC
         ->  Index Scan using ix_notifications_template_id on notifications  (cost=0.56..5321.81 rows=258 width=935)
               Index Cond: (template_id = 'xxxxx'::uuid)
               Filter: (((key_type)::text <> 'test'::text) AND (notification_type = 'sms'::notification_type))
 Planning time: 1.102 ms
 Execution time: 0.584 ms
This commit is contained in:
Rebecca Law
2018-03-16 14:12:59 +00:00
parent 2a3095d5c5
commit a308815793
3 changed files with 13 additions and 12 deletions

View File

@@ -96,10 +96,11 @@ def dao_get_template_usage(service_id, limit_days=None):
@statsd(namespace="dao")
def dao_get_last_template_usage(template_id):
def dao_get_last_template_usage(template_id, template_type):
return Notification.query.filter(
Notification.template_id == template_id,
Notification.key_type != KEY_TYPE_TEST
Notification.key_type != KEY_TYPE_TEST,
Notification.notification_type == template_type
).order_by(
desc(Notification.created_at)
).first()

View File

@@ -63,7 +63,7 @@ def get_template_statistics_for_template_id(service_id, template_id):
raise InvalidRequest(errors, status_code=404)
data = None
notification = dao_get_last_template_usage(template_id)
notification = dao_get_last_template_usage(template_id, template.template_type)
if notification:
data = notification_with_template_schema.dump(notification).data