我做了一些没有成功的搜索,我想知道是否有更好的方法来重写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
语句以提高性能吗?
答案 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