Просмотр исходного кода

perf(core): Optimize some SQL queries in hot code paths for Orders

Relates to #226. When using `findOne()`, two queries are generated since it uses a similar code path to `findMany({ limit: 1 })`. This change switches a couple of queries to use the QueryBuilder API, which allows the same data to be retrieved but with only a single query.
Michael Bromley 6 лет назад
Родитель
Сommit
691f579519

+ 11 - 4
packages/core/src/service/services/auth.service.ts

@@ -97,10 +97,17 @@ export class AuthService {
      * Looks for a valid session with the given token and returns one if found.
      * Looks for a valid session with the given token and returns one if found.
      */
      */
     async validateSession(token: string): Promise<Session | undefined> {
     async validateSession(token: string): Promise<Session | undefined> {
-        const session = await this.connection.getRepository(Session).findOne({
-            where: { token, invalidated: false },
-            relations: ['user', 'user.roles', 'user.roles.channels', 'activeOrder'],
-        });
+        const session = await this.connection
+            .getRepository(Session)
+            .createQueryBuilder('session')
+            .leftJoinAndSelect('session.activeOrder', 'activeOrder')
+            .leftJoinAndSelect('session.user', 'user')
+            .leftJoinAndSelect('user.roles', 'roles')
+            .leftJoinAndSelect('roles.channels', 'channels')
+            .where('session.token = :token', { token })
+            .andWhere('session.invalidated = false')
+            .getOne();
+
         if (session && session.expires > new Date()) {
         if (session && session.expires > new Date()) {
             await this.updateSessionExpiry(session);
             await this.updateSessionExpiry(session);
             return session;
             return session;

+ 18 - 16
packages/core/src/service/services/order.service.ts

@@ -91,18 +91,20 @@ export class OrderService {
     }
     }
 
 
     async findOne(ctx: RequestContext, orderId: ID): Promise<Order | undefined> {
     async findOne(ctx: RequestContext, orderId: ID): Promise<Order | undefined> {
-        const order = await this.connection.getRepository(Order).findOne(orderId, {
-            relations: [
-                'customer',
-                'lines',
-                'lines.productVariant',
-                'lines.productVariant.taxCategory',
-                'lines.featuredAsset',
-                'lines.items',
-                'lines.items.fulfillment',
-                'lines.taxCategory',
-            ],
-        });
+        const order = await this.connection
+            .getRepository(Order)
+            .createQueryBuilder('order')
+            .leftJoinAndSelect('order.customer', 'customer')
+            .leftJoinAndSelect('order.lines', 'lines')
+            .leftJoinAndSelect('lines.productVariant', 'productVariant')
+            .leftJoinAndSelect('productVariant.taxCategory', 'prodVariantTaxCategory')
+            .leftJoinAndSelect('productVariant.productVariantPrices', 'prices')
+            .leftJoinAndSelect('lines.featuredAsset', 'featuredAsset')
+            .leftJoinAndSelect('lines.items', 'items')
+            .leftJoinAndSelect('items.fulfillment', 'fulfillment')
+            .leftJoinAndSelect('lines.taxCategory', 'lineTaxCategory')
+            .where('order.id = :orderId', { orderId })
+            .getOne();
         if (order) {
         if (order) {
             order.lines.forEach(line => {
             order.lines.forEach(line => {
                 line.productVariant = translateDeep(
                 line.productVariant = translateDeep(
@@ -280,7 +282,7 @@ export class OrderService {
         if (customFields != null) {
         if (customFields != null) {
             orderLine.customFields = customFields;
             orderLine.customFields = customFields;
         }
         }
-        await this.connection.getRepository(OrderLine).save(orderLine);
+        await this.connection.getRepository(OrderLine).save(orderLine, { reload: false });
         return this.applyPriceAdjustments(ctx, order);
         return this.applyPriceAdjustments(ctx, order);
     }
     }
 
 
@@ -788,9 +790,9 @@ export class OrderService {
             order: { priorityScore: 'ASC' },
             order: { priorityScore: 'ASC' },
         });
         });
         order = await this.orderCalculator.applyPriceAdjustments(ctx, order, promotions);
         order = await this.orderCalculator.applyPriceAdjustments(ctx, order, promotions);
-        await this.connection.getRepository(Order).save(order);
-        await this.connection.getRepository(OrderItem).save(order.getOrderItems());
-        await this.connection.getRepository(OrderLine).save(order.lines);
+        await this.connection.getRepository(Order).save(order, { reload: false });
+        await this.connection.getRepository(OrderItem).save(order.getOrderItems(), { reload: false });
+        await this.connection.getRepository(OrderLine).save(order.lines, { reload: false });
         return order;
         return order;
     }
     }