我有一个包含2个查询的MySQL联合,在索引列上完成了ORDER BY。什么是更好的性能,单独按每个联合查询排序,或者在我目前拥有的联盟结束时排序?
(SELECT pep.P_Surname, pep.P_FirstName, pep.P_ID, adm.Loc_ID AS lid
FROM lup_people pep
JOIN tr_adm adm ON pep.P_ID=adm.P_ID
WHERE (P_FirstName LIKE 'g%'
OR P_Surname LIKE 'g%')
AND pep.active = 'Y')
UNION
(SELECT pep.P_Surname, pep.P_FirstName, pep.P_ID, vil.Loc_ID AS lid
FROM lup_people pep
JOIN tr_village vil ON (pep.P_ID=vil.P1_ID OR pep.P_ID=vil.P2_ID)
WHERE (P_FirstName LIKE 'g%'
OR P_Surname LIKE 'g%')
AND pep.active = 'Y')
ORDER BY P_Surname,P_FirstName LIMIT 50
VS
(SELECT pep.P_Surname, pep.P_FirstName, pep.P_ID, adm.Loc_ID AS lid
FROM lup_people pep
JOIN tr_adm adm ON pep.P_ID=adm.P_ID
WHERE (P_FirstName LIKE 'g%'
OR P_Surname LIKE 'g%')
AND pep.active = 'Y' ORDER BY P_Surname,P_FirstName LIMIT 50)
UNION
(SELECT pep.P_Surname, pep.P_FirstName, pep.P_ID, vil.Loc_ID AS lid
FROM lup_people pep
JOIN tr_village vil ON (pep.P_ID=vil.P1_ID OR pep.P_ID=vil.P2_ID)
WHERE (P_FirstName LIKE 'g%'
OR P_Surname LIKE 'g%')
AND pep.active = 'Y' ORDER BY P_Surname,P_FirstName LIMIT 50)
答案 0 :(得分:1)
(1)您应该使用union all
,除非您打算通过union
删除重复项。
(2)查询不同。第一个返回100行。第二行返回50行。
(3)您不应该依赖union
查询的结果排序。如果您希望按特定顺序排列结果,请在order by
之后使用union
。
(4)很可能,最快的方法是使用left outer join
。它看起来像是:
SELECT pep.P_Surname, pep.P_FirstName, pep.P_ID,
coalesce(adm.Loc_ID, vil.loc_id, vil2.loc_id) AS lid
FROM lup_people pep LEFT JOIN
tr_adm adm
ON pep.P_ID = adm.P_ID LEFT JOIN
tr_village vil
ON pep.P_ID = vil.P1_ID LEFT JOIN
tr_village vil2
ON pep.P_ID = vil2.P2_ID
WHERE (P_FirstName LIKE 'g%' OR P_Surname LIKE 'g%') AND pep.active = 'Y'
ORDER BY P_Surname, P_FirstName
LIMIT 50;
答案 1 :(得分:0)
根据数据量,它可以采用任何一种方式。你面临的问题是这个。在您的第一个查询中,您正在进行选择 - 获取符合条件的所有可能答案,然后应用order by子句,最后应用限制。所以,如果你有1000个合格的记录,你仍然需要通过它们进行订购,然后获得前50名。
第二个将至少将每个结果集从每个结果集减少到50,最多留下100个记录。