首页 > 解决方案 > 为什么我的 Sequelize 查询这么慢?(使用 findAll 的嵌套连接)

问题描述

我看到一个问题,因为我在 Schedule 模型上包含了更多 DayAvailability 嵌套关联,因此我的查询速度呈指数级增长。目标是序列化 User 实例以包含所有关联的实例。

这是表结构:

// User model

const User = sequelize.define('user', {
    id: {
      type: DataTypes.UUID,
      primaryKey: true
    }
}, {});
});

User.associate = function (models) {
  User.hasOne(models.Schedule);
};
// Schedule model

const Schedule = sequelize.define('schedule', {
  id: {
    type: DataTypes.UUID,
    primaryKey: true
  },
  userId: DataTypes.UUID
}, {
  hooks: {
    async afterCreate(instance, options) {
      await instance.createMonday();
      await instance.createTuesday();
      await instance.createWednesday();
      await instance.createThursday();
      await instance.createFriday();
      await instance.createSaturday();
      await instance.createSunday();
    }
  }
});

Schedule.associate = function(models) {
  Schedule.belongsTo(models.User);
  Schedule.hasOne(models.DayAvailability, { as: 'Monday', foreignKey: 'scheduleId' });
  Schedule.hasOne(models.DayAvailability, { as: 'Tuesday', foreignKey: 'scheduleId' });
  Schedule.hasOne(models.DayAvailability, { as: 'Wednesday', foreignKey: 'scheduleId' });
  Schedule.hasOne(models.DayAvailability, { as: 'Thursday', foreignKey: 'scheduleId' });
  Schedule.hasOne(models.DayAvailability, { as: 'Friday', foreignKey: 'scheduleId' });
  Schedule.hasOne(models.DayAvailability, { as: 'Saturday', foreignKey: 'scheduleId' });
  Schedule.hasOne(models.DayAvailability, { as: 'Sunday', foreignKey: 'scheduleId' });
};
// DayAvailability model

const DayAvailability = sequelize.define('day_availability', {
  id: {
    type: DataTypes.UUID,
    primaryKey: true
  },
  scheduleId: DataTypes.UUID
}, {});

DayAvailability.associate = function(models) {
  DayAvailability.belongsTo(models.Schedule);
};

(为简洁起见,省略其他字段)

此设置确实按预期工作。我可以获得一个包含嵌套 Schedule 实例的 User 实例,但是包含嵌套在 Schedule 实例中的 DayAvailability 实例会导致查询速度非常慢。如果我从查询中省略了一些 DayAvailability 实例关联,它不会那么慢。

// User controller

const include = { model: Schedule, include: [
    { association: 'Monday' },  // only Monday - ~0.1 sec
    { association: 'Tuesday' },  // include Tues - ~0.5 sec
    { association: 'Wednesday' },  // include Wed - ~1.5 sec
    { association: 'Thursday' },   // include Thurs - 2+ sec
    { association: 'Friday' },
    { association: 'Saturday' },
    { association: 'Sunday' }   // include all - times out 
]};

await User.findOne({
  where: { id: '123' },
  include
});

关于为什么这个查询如此慢的任何想法?包含这样的嵌套关联不是很好吗?

谢谢你的帮助。


编辑:这是从上述 Sequelize 函数生成的 SQL 查询。模型中的其他字段作为提示包含在 SQL 查询中。

https://gist.github.com/FilmCoder/0afba42ffefb8f1e483699eb7ca2ac3b

标签: postgresqlsequelize.jssequelize-cli

解决方案


我可以提供更多信息。DayAvailability 记录将来可能会扩展为更多列以包含更多信息,例如一个人可用的时间范围、他们所在的时区、他们当天开放程度的跟踪记录等。 .

每个时间表将有 7 条 DayAvailability 记录,因为“Schedule”代表一周,而 DayAvailability 代表该周中的某一天。

我们想知道我们是否在使用外键做一些根本性的错误,并且有一种方法可以在关系数据库中有效地进行这项工作。

我会对此发表评论,但由于某种原因堆栈溢出不会让我这样做。


推荐阅读