在某些情况下,LoopBack似乎以非常低效的方式处理关系数据库。我遇到了性能问题,我想知道是否有人找到了解决问题的方法。
为了说明这一点,我创建了一个包含三个表和简单的多对多关系的MySQL数据库,如下所示。
这是一个非常标准和常见的情况(顺便说一下,我直接从LoopBack的文档中借用)。
以下是我填充表格的方式:
mysql> SELECT * FROM physician;
+----+----------+
| id | name |
+----+----------+
| 1 | Smith |
| 2 | Johnson |
| 3 | Williams |
| 4 | Jones |
+----+----------+
mysql> SELECT * FROM patient;
+----+----------+
| id | name |
+----+----------+
| 1 | Anderson |
| 2 | Jackson |
| 3 | White |
| 4 | Roberts |
| 5 | Lewis |
| 6 | Clark |
| 7 | Morgan |
+----+----------+
mysql> SELECT * FROM appointment;
+----+--------------+------------+------------+
| id | physician_id | patient_id | date |
+----+--------------+------------+------------+
| 6 | 1 | 1 | 2014-06-12 |
| 7 | 1 | 3 | 2014-06-12 |
| 8 | 1 | 5 | 2014-06-12 |
| 9 | 2 | 2 | 2014-06-12 |
| 10 | 2 | 4 | 2014-06-12 |
| 11 | 3 | 7 | 2014-06-12 |
| 12 | 2 | 2 | 2014-06-13 |
+----+--------------+------------+------------+
现在,假设我们想找到与约翰逊博士(physician_id = 2
)约会的患者名单。有几种合理的方法可以实现这一目标,例如:
SELECT * FROM patient WHERE id IN( SELECT patient_id FROM appointment WHERE physician_id = 2 )
或
SELECT patient.* FROM patient JOIN appointment ON patient.id = appointment.patient_id WHERE appointment.physician_id = 2
LoopBack在后台做的事情完全是另一回事:
SELECT `id`, `physician_id`, `patient_id`, `date` FROM `appointment` WHERE `physician_id` = 2 ORDER BY `id`
SELECT * FROM `patient` WHERE `id` = 2 LIMIT 1
SELECT * FROM `patient` WHERE `id` = 4 LIMIT 1
SELECT * FROM `patient` WHERE `id` = 2 LIMIT 1
我们在这里看到的是,它将首先搜索所有医生约翰逊的约会(第一次查询),然后在patient
表中搜索与先前查询找到的患者ID(最后3个查询)。结果如下:
[
{
"id": 2,
"name": "Jackson"
},
{
"id": 4,
"name": "Roberts"
},
{
"id": 2,
"name": "Jackson"
}
]
这看起来非常低效。我们可以看到上面的4个SQL查询,这是有效1 + n
个查询,其中n
是患者数量!换句话说,LoopBack将使MySQL扫描patient
表的次数与第一次查询中找到的患者数一样多。显然,随着患者表中记录数量的增加,这变得非常低效。
还有其他方法可以更有效地实现这一目标吗?