什么是更快,次选择或不同(MySQL)?

时间:2016-05-12 11:39:28

标签: mysql sql mariadb

让我描述一下我的怀疑。我有一个系统,我有三个实体,医生,病人和预约。预约有医生的身份和患者身份。

我现在需要检索所有与具体医生预约的患者,而且我不确定什么会更快,一个独特的或用于id的subselect,这些是查询:

使用distinct->

SELECT DISTINCT patient.id, patient.name, patient.surname FROM
appointment INNER JOIN patient ON patient.id = appointment.patientid WHERE
appointment.doctorid = @id;

使用subselect->

SELECT patient.id, patient.name, patient.surname FROM patient
WHERE patient.id IN (select appointment.patientid FROM appointment 
WHERE appointment.doctorid = @id);

不确定这会影响,系统将在MariaDB集群上运行。

2 个答案:

答案 0 :(得分:6)

与任何性能问题一样,您应该测试您的数据和硬件。第一个版本中的可疑问题DISTINCT之后JOIN;这可能需要大量的额外处理。

您可以将第二个写为:

SELECT p.id, p.name, p.surname
FROM patient p
WHERE p.id IN (select a.patientid FROM appointment a WHERE a.doctorid = @id);

为此,您需要appointment(doctorid, patientid)上的索引。

你也可以考虑这个版本:

select p.id, p.name, p.surname
from patient p join
     (select distinct appointment.patientid
      from appointment
      where appointment.doctorid = @id
     ) a
     on p.id = a.patientid;

这特别需要相同的索引。这会推送distinct,因此它只在单个表上运行,这意味着MySQL可以使用索引进行该操作。

这一个:

SELECT p.id, p.name, p.surname
FROM patient p
WHERE EXISTS (select 1
              from appointment a
              where a.doctorid = @id and a.patientid = p.id
             );

此查询需要appointment(patientid, doctorid)上的索引。它需要对patient进行全表扫描,并在每行上进行快速索引查找。这通常是最快的方法,具体取决于数据。

注意:哪个查询执行得更好也可能取决于数据的大小和分布。

答案 1 :(得分:1)

都不是。

这些遭受“膨胀 - 放气”。也就是说,JOIN导致临时表中的行数更多,只能修剪回你需要的行。这很昂贵。 (它可以为COUNTSUM提供错误的答案。)

SELECT DISTINCT ... JOIN ...
and
SELECT ... JOIN ... GROUP BY ...

由于优化程序限制,这表现不佳:

... IN ( SELECT ... )

这就是你想要的:

SELECT ...
    FROM ( SELECT id FROM ... WHERE ... )
    JOIN ...

如果子查询需要DISTINCTGROUP BY和/或LIMIT,则会特别好。这是因为它会在执行JOIN之前创建一小组行,从而减少所需的JOINs次数。