SQL LEFT JOIN OR条件的更好方法

时间:2017-06-30 04:02:58

标签: mysql sql left-join

我做了一些没有成功的搜索,我想知道是否有更好的方法来重写sql查询,因为OR中的LEFT JOIN条件会导致性能下降:(

例如:

SELECT DISTINCT * FROM computers
LEFT JOIN monitors ON computers.brand = monitors.brand
LEFT JOIN keyboards ON computers.type = keyboards.type
LEFT JOIN accessories ON accessories.id = keyboards.id OR accessories.id = monitors.id
GROUP BY computers.id
ORDER BY computers.id DESC

对于愚蠢的问题感到抱歉,但是有可能重写OR语句以提高性能吗?

2 个答案:

答案 0 :(得分:1)

我怀疑它会有什么不同,但你可以试试这个:

SELECT DISTINCT * 
FROM computers
LEFT JOIN monitors ON computers.brand = monitors.brand
LEFT JOIN keyboards ON computers.type = keyboards.type
LEFT JOIN accessories ON a1.id IN (keyboards.id, monitors.id)
GROUP BY computers.id
ORDER BY computers.id DESC

如果您习惯使用两组配件列(可能在coalesce()列表中使用SELECT一组),您也可以两次加入同一个表:

SELECT DISTINCT * FROM computers
LEFT JOIN monitors ON computers.brand = monitors.brand
LEFT JOIN keyboards ON computers.type = keyboards.type
LEFT JOIN accessories a1 ON a1.id = keyboards.id 
LEFT JOIN accessories a2 ON a2.id = monitors.id
GROUP BY computers.id
ORDER BY computers.id DESC

而且,fwiw,这个查询在大多数现代数据库引擎中都不合法。如果你想GROUP BY一个字段,ANSI SQL标准说你不能只将*(即使DISTINCT}放在SELECT列表中,因为你没有当数据库汇总组时,指定要保留哪些值以及丢弃哪些值...结果是未定义的,这是一件坏事。

答案 1 :(得分:0)

您正在执行SELECT DISTINCT *,因此检查您的整个记录​​在其获取的所有行中是唯一的,这是3个表值。它可能已经是独一无二的,如果您的主键和唯一索引设置正确,它绝对是唯一的,所以就把它取出来。

如果您的主键和索引未设置,请先执行此操作。名为id。

的字段的主键

那和SELECT *会产生很大的开销,因为它必须弄清楚其余列的内容。

在不知道表格结构实际存在的情况下进行猜测:由于您要按GROUP BY computers.id进行分组,请将其放在SELECT中,然后将其从GROUP BY中删除。

SELECT DISTINCT computers.id