什么更快,子选择或不同(MySQL)?
What is faster, subselect or distinct (MySQL)?
说一下我的疑惑。我的系统中有三个实体,医生、患者和预约。一个约会有医生的id和病人的id。
我现在需要检索所有与具体医生有预约的患者,我不确定什么会更快,id 的不同选择或子选择,这些是查询:
使用不同->
SELECT DISTINCT patient.id, patient.name, patient.surname FROM
appointment INNER JOIN patient ON patient.id = appointment.patientid WHERE
appointment.doctorid = @id;
使用子选择->
SELECT patient.id, patient.name, patient.surname FROM patient
WHERE patient.id IN (select appointment.patientid FROM appointment
WHERE appointment.doctorid = @id);
不确定这是否会影响,系统将 运行 在 MariaDB 集群上。
与任何性能问题一样,您应该测试您的数据和硬件。疑似问题在第一个版本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
,因此它仅对单个 table 进行操作,这意味着 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
进行完整的 table 扫描,并在每一行上进行快速索引查找。这通常可能是最快的方法,具体取决于数据。
注意:哪个查询执行得更好也可能取决于数据的大小和分布。
我认为约会应该有一个 id 才能加入...所以这是一个代码...我希望它有帮助
SELECT patient.id, patient.name, patient.surname FROM patient
INNER JOIN appointment ON appointment.id = patient.patientid
INNER JOIN doctor ON doctor.id = appointment.id
WHERE appointment.doctorid = @id
都没有。
这些患有"inflate-deflate"。也就是说,JOIN
导致临时 table 中有更多行,只是为了修剪回您需要的行。这是昂贵的。 (它可能会给出 COUNT
和 SUM
的错误答案。)
SELECT DISTINCT ... JOIN ...
and
SELECT ... JOIN ... GROUP BY ...
由于优化器的限制,这表现不佳:
... IN ( SELECT ... )
这就是你想要的:
SELECT ...
FROM ( SELECT id FROM ... WHERE ... )
JOIN ...
如果子查询需要DISTINCT
、GROUP BY
、and/orLIMIT
就特别好。这是因为它会在执行 JOIN
之前创建一小组行,从而减少所需的 JOINs
数量。
说一下我的疑惑。我的系统中有三个实体,医生、患者和预约。一个约会有医生的id和病人的id。
我现在需要检索所有与具体医生有预约的患者,我不确定什么会更快,id 的不同选择或子选择,这些是查询:
使用不同->
SELECT DISTINCT patient.id, patient.name, patient.surname FROM
appointment INNER JOIN patient ON patient.id = appointment.patientid WHERE
appointment.doctorid = @id;
使用子选择->
SELECT patient.id, patient.name, patient.surname FROM patient
WHERE patient.id IN (select appointment.patientid FROM appointment
WHERE appointment.doctorid = @id);
不确定这是否会影响,系统将 运行 在 MariaDB 集群上。
与任何性能问题一样,您应该测试您的数据和硬件。疑似问题在第一个版本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
,因此它仅对单个 table 进行操作,这意味着 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
进行完整的 table 扫描,并在每一行上进行快速索引查找。这通常可能是最快的方法,具体取决于数据。
注意:哪个查询执行得更好也可能取决于数据的大小和分布。
我认为约会应该有一个 id 才能加入...所以这是一个代码...我希望它有帮助
SELECT patient.id, patient.name, patient.surname FROM patient
INNER JOIN appointment ON appointment.id = patient.patientid
INNER JOIN doctor ON doctor.id = appointment.id
WHERE appointment.doctorid = @id
都没有。
这些患有"inflate-deflate"。也就是说,JOIN
导致临时 table 中有更多行,只是为了修剪回您需要的行。这是昂贵的。 (它可能会给出 COUNT
和 SUM
的错误答案。)
SELECT DISTINCT ... JOIN ...
and
SELECT ... JOIN ... GROUP BY ...
由于优化器的限制,这表现不佳:
... IN ( SELECT ... )
这就是你想要的:
SELECT ...
FROM ( SELECT id FROM ... WHERE ... )
JOIN ...
如果子查询需要DISTINCT
、GROUP BY
、and/orLIMIT
就特别好。这是因为它会在执行 JOIN
之前创建一小组行,从而减少所需的 JOINs
数量。