Почему мой запрос Sequelize такой медленный? (вложенные соединения с использованием findAll) - PullRequest
0 голосов
/ 16 апреля 2020

Я вижу проблему, когда мой запрос экспоненциально медленнее, поскольку я включаю больше вложенных связей DayAvailability в модель Schedule. Цель состоит в том, чтобы сериализовать экземпляр 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);
};

(для краткости опущены другие поля)

Эта настройка действительно работает как задумано. Я могу получить экземпляр User с включенным вложенным экземпляром Schedule, однако включение экземпляров DayAvailability, вложенных в экземпляр Schedule, вызывает смехотворно медленный запрос. Если я опущу некоторые ассоциации экземпляров 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
});

Есть идеи, почему этот запрос невероятно медленный? Разве не стоит включать вложенные ассоциации, подобные этой?

Спасибо за вашу помощь.


Редактировать: вот запрос SQL, который генерируется из вышеуказанной функции Sequelize. Другие поля из моделей включены в запрос SQL в качестве заголовков.

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

1 Ответ

0 голосов
/ 18 апреля 2020

Я могу дать немного больше информации. В будущем запись DayAvailability может расшириться за счет добавления большего количества столбцов, включая дополнительную информацию, такую ​​как временной диапазон, когда человек доступен, в каком часовом поясе он находится, его послужной список того, насколько он открыт в тот день, и т. Д. c ...

И в расписании будет 7 записей DayAvailability, поскольку «Расписание» представляет одну неделю, а DayAvailability - один день этой недели.

Нам интересно, Вы делаете что-то в корне с внешними ключами, и есть способ сделать это эффективно в реляционной базе данных.

Я бы сделал это комментарием, но по какой-то причине переполнение стека не позволит мне.

...