【发布时间】:2020-04-15 23:02:25
【问题描述】:
我看到一个问题,即我的查询速度呈指数级增长,因为我在 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
【问题讨论】:
-
Schedule.hasOne(models.DayAvailability, { as: 'Tuesday', foreignKey: 'scheduleId' }); Schedule.hasOne(models.DayAvailability, { as: 'Wednesday', foreignKey: 'scheduleId' }); ...看起来像重复的不必要的关联。他们将映射完全相同的记录
-
看来你把7个表记录相乘所以总记录量很大!
-
@Anatoly 表示同意,但是如何在 Schedule 模型上创建七个不同的字段,每个字段都映射到 DayAvailability 模型实例?顺便说一句,我最终将这些字段中的每一个都设置为 JSON 而不是单独的模型。它运作良好,但我没有回答这个问题,因为它仍然让我感到困惑。
-
DayAvailability 中有多少条记录对应一个日程表 ID?根据星期几从 0 到 7?
标签: postgresql sequelize.js sequelize-cli