Browse Source

Optimize resource list query

Instead of 2 queries per resource
to fetch min and max sample timestamp
value, replaced with a single query of
similar cost. Another query of lesser
cost to retrieve the resource details.

Change-Id: I50d4a63a387e6a83c6090ebeafe7a330c5fda61c
Closes-Bug: #1404076
tags/2015.1.0b2
Rohit Jaiswal 4 years ago
parent
commit
e5ad0bac86
1 changed files with 43 additions and 32 deletions
  1. 43
    32
      ceilometer/storage/impl_sqlalchemy.py

+ 43
- 32
ceilometer/storage/impl_sqlalchemy.py View File

@@ -417,38 +417,49 @@ class Connection(base.Connection):
417 417
                                        require_meter=False)
418 418
 
419 419
         for res_id in res_q.all():
420
-            # get latest Sample
421
-            max_q = (session.query(models.Sample)
422
-                     .join(models.Resource,
423
-                           models.Resource.internal_id ==
424
-                           models.Sample.resource_id)
425
-                     .filter(models.Resource.resource_id == res_id[0]))
426
-            max_q = make_query_from_filter(session, max_q, s_filter,
427
-                                           require_meter=False)
428
-            max_q = max_q.order_by(models.Sample.timestamp.desc(),
429
-                                   models.Sample.id.desc()).limit(1)
430
-
431
-            # get the min timestamp value.
432
-            min_q = (session.query(models.Sample.timestamp)
433
-                     .join(models.Resource,
434
-                           models.Resource.internal_id ==
435
-                           models.Sample.resource_id)
436
-                     .filter(models.Resource.resource_id == res_id[0]))
437
-            min_q = make_query_from_filter(session, min_q, s_filter,
438
-                                           require_meter=False)
439
-            min_q = min_q.order_by(models.Sample.timestamp.asc()).limit(1)
440
-
441
-            sample = max_q.first()
442
-            if sample:
443
-                yield api_models.Resource(
444
-                    resource_id=sample.resource.resource_id,
445
-                    project_id=sample.resource.project_id,
446
-                    first_sample_timestamp=min_q.first().timestamp,
447
-                    last_sample_timestamp=sample.timestamp,
448
-                    source=sample.resource.source_id,
449
-                    user_id=sample.resource.user_id,
450
-                    metadata=sample.resource.resource_metadata
451
-                )
420
+
421
+            # get max and min sample timestamp value
422
+            min_max_q = (session.query(func.max(models.Sample.timestamp)
423
+                                       .label('max_timestamp'),
424
+                                       func.min(models.Sample.timestamp)
425
+                                       .label('min_timestamp'))
426
+                                .join(models.Resource,
427
+                                      models.Resource.internal_id ==
428
+                                      models.Sample.resource_id)
429
+                                .filter(models.Resource.resource_id ==
430
+                                        res_id[0]))
431
+
432
+            min_max_q = make_query_from_filter(session, min_max_q, s_filter,
433
+                                               require_meter=False)
434
+
435
+            min_max = min_max_q.first()
436
+
437
+            # get resource details for latest sample
438
+            res_q = (session.query(models.Resource.resource_id,
439
+                                   models.Resource.user_id,
440
+                                   models.Resource.project_id,
441
+                                   models.Resource.source_id,
442
+                                   models.Resource.resource_metadata)
443
+                            .join(models.Sample,
444
+                                  models.Sample.resource_id ==
445
+                                  models.Resource.internal_id)
446
+                            .filter(models.Sample.timestamp ==
447
+                                    min_max.max_timestamp)
448
+                            .filter(models.Resource.resource_id ==
449
+                                    res_id[0])
450
+                            .order_by(models.Sample.id.desc()).limit(1))
451
+
452
+            res = res_q.first()
453
+
454
+            yield api_models.Resource(
455
+                resource_id=res.resource_id,
456
+                project_id=res.project_id,
457
+                first_sample_timestamp=min_max.min_timestamp,
458
+                last_sample_timestamp=min_max.max_timestamp,
459
+                source=res.source_id,
460
+                user_id=res.user_id,
461
+                metadata=res.resource_metadata
462
+            )
452 463
 
453 464
     def get_meters(self, user=None, project=None, resource=None, source=None,
454 465
                    metaquery=None, pagination=None):

Loading…
Cancel
Save