1. Backgroud
API slow in production and a OOM error in log.
2. Research
2.1 code review
check the code and debug the slow code looks like below:
1 | const org = await DB.Org.findByPk(orgId, { |
the above code use the ORM(Sequelize) find the org and relation entites(project/user/subject).
2.2 find/format/simplify sql
1 | SELECT * |
2.3 separate the sql and exec
- only left join Subjects: 1512 rows, 35ms
1
2
3
4SELECT *
FROM `Orgs` `Org`
LEFT JOIN `Subjects` `Subjects` ON `Org`.`id` = `Subjects`.`orgId`
WHERE `Org`.`id` = 1; - only left join Projects: 635 rows, 26ms
1
2
3
4SELECT *
FROM `Orgs` `Org`
LEFT JOIN `Projects` `Projects` ON `Org`.`id` = `Projects`.`orgId`
WHERE `Org`.`id` = 1; - only left join Users: 14 rows, 7ms
1
2
3
4
5
6# only for left join Users
# 14 rows, 7ms
SELECT *
FROM `Orgs` `Org`
LEFT JOIN `Users` `Users` ON `Org`.`id` = `Users`.`orgId` # 14
WHERE `Org`.`id` = 1;
The reason is very clear now. If we join three tables, the total rows count is 1512 * 635 * 14 = 13441680.
13441680 rows with all columns are too big for v8 engine in nodejs.
3. How to resolve?
Separate query for Subject/User/Project is the solution. The three paralle query maybe a better solution.