在某些情况下,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 |
+----+--------------+------------+------------+
现在,假设我们要查找与 Johnson 博士(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
我们在这里看到的是,它将首先搜索 Johnson 医生的所有预约(第一个查询),然后在patient
表中搜索通过前一个查询找到的患者 ID(最后 3 个查询)。结果如下:
[
{
"id": 2,
"name": "Jackson"
},
{
"id": 4,
"name": "Roberts"
},
{
"id": 2,
"name": "Jackson"
}
]
这看起来非常低效。上面我们可以看到4条SQL查询,都是有效1 + n
查询,其中n
患者的数量是多少!换句话说,LoopBack 将使 MySQL 扫描该patient
表的次数与第一次查询中找到的患者数量一样多。显然,随着患者表中记录数量的增加,这变得非常低效。
有没有其他方法可以更有效地实现这一目标?