我做了一些搜索,但没有成功,我想知道是否有更好的方法来重写sql查询,因为LEFT JOIN中的这个OR条件会降低性能:(
例如:
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语句来提高性能?
发布于 2017-06-30 12:24:04
我怀疑这会有什么不同,但你可以试试这个:
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如果您愿意拥有两组附件列(可能在SELECT列表中使用coalesce() a bunch ),还可以两次连接到同一个表:
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另外,这种查询在大多数现代数据库引擎中都是不合法的。如果您想要GROUP BY一个字段,ANSI SQL标准规定您不能只将* (即使使用DISTINCT)放在SELECT列表中,因为您还没有指定在数据库滚动该组时保留和丢弃哪些值...结果是不确定的,这是一件坏事。
发布于 2017-06-30 21:29:59
您正在执行SELECT DISTINCT *,因此它检查您的整个记录在它获得的所有行中是否是唯一的,这相当于3个表。它可能已经是唯一的,如果你的主键和唯一索引设置正确,它肯定是唯一的,所以把它拿出来就行了。
如果您的主键和索引没有设置,请先进行设置。名为id的字段的主键。
这和SELECT *产生了很大的开销,因为它必须找出您的其余列是什么。
在不知道表结构实际是什么的情况下进行猜测:因为您是按GROUP BY computers.id分组的,所以将其放入SELECT中,并将其从GROUP BY中删除。
SELECT DISTINCT computers.id
https://stackoverflow.com/questions/44838393
复制相似问题