|
47 | 47 | from sqlalchemy.orm import aliased |
48 | 48 | from sqlalchemy.orm import joinedload |
49 | 49 | from sqlalchemy.orm import noload |
| 50 | +from sqlalchemy.orm import subqueryload |
50 | 51 | from sqlalchemy.orm import undefer |
51 | 52 | from sqlalchemy.schema import Table |
52 | 53 | from sqlalchemy import sql |
@@ -1266,13 +1267,27 @@ def _build_instance_get(context, columns_to_join=None): |
1266 | 1267 | continue |
1267 | 1268 | if 'extra.' in column: |
1268 | 1269 | query = query.options(undefer(column)) |
| 1270 | + elif column in ['metadata', 'system_metadata']: |
| 1271 | + # NOTE(melwitt): We use subqueryload() instead of joinedload() for |
| 1272 | + # metadata and system_metadata because of the one-to-many |
| 1273 | + # relationship of the data. Directly joining these columns can |
| 1274 | + # result in a large number of additional rows being queried if an |
| 1275 | + # instance has a large number of (system_)metadata items, resulting |
| 1276 | + # in a large data transfer. Instead, the subqueryload() will |
| 1277 | + # perform additional queries to obtain metadata and system_metadata |
| 1278 | + # for the instance. |
| 1279 | + query = query.options(subqueryload(column)) |
1269 | 1280 | else: |
1270 | 1281 | query = query.options(joinedload(column)) |
1271 | 1282 | # NOTE(alaski) Stop lazy loading of columns not needed. |
1272 | 1283 | for col in ['metadata', 'system_metadata']: |
1273 | 1284 | if col not in columns_to_join: |
1274 | 1285 | query = query.options(noload(col)) |
1275 | | - return query |
| 1286 | + # NOTE(melwitt): We need to use order_by(<unique column>) so that the |
| 1287 | + # additional queries emitted by subqueryload() include the same ordering as |
| 1288 | + # used by the parent query. |
| 1289 | + # https://docs.sqlalchemy.org/en/13/orm/loading_relationships.html#the-importance-of-ordering |
| 1290 | + return query.order_by(models.Instance.id) |
1276 | 1291 |
|
1277 | 1292 |
|
1278 | 1293 | def _instances_fill_metadata(context, instances, manual_joins=None): |
|
0 commit comments