我从学校接受挑战以优化此查询(这是理论问题)
挑战:
SELECT
n.node_id,
MIN(LEAST(n.date,ec.date)) date
FROM
n, ec
WHERE
(n.node_id = ec.node_id_from OR n.node_id = ec.node_id_to)
AND n.date - ec.date > 0
GROUP BY
n.node_id;
我努力优化此查询并需要与人分享
SELECT
n.node_id, LEAST (n.date, ec.date) date
FROM
n
INNER JOIN
ec ON (n.node_id = ec.node_id_from OR n.node_id = ec.node_id_to)
WHERE
n.date - ec.date > 0
我做了什么:我删除了min函数和group by,因为函数最少只返回string中的最小值。
其次,我使用此查询添加了内部联接。
我的解决方案是否正常或您有更好的选择?
答案 0 :(得分:1)
当想要评估单个列与2个或更多值的相等性时,您可以使用IN而不是多个OR:
SELECT n.node_id, MIN(ec.date) as date
FROM n
JOIN ec
ON n.node_id IN (ec.node_id_from, ec.node_id_to) AND ec.date < n.date
GROUP BY n.node_id;
它更简洁,并且使用n.node_id上的索引的可能性更高(如果存在)。
另外,请参阅旧的post
只使用min(ec.date)
代替MIN(LEAST(n.date,ec.date))
因为JOIN已强制ec.date
无论如何都要低于n.date
。
还要注意像
这样的where子句where (x >= y and x <= z)
可以更改为
where (x between y and z)
答案 1 :(得分:0)
or
子句中的 on
是性能杀手。我想你打算:
SELECT n.node_id, MIN(LEAST(n.date, ec.date)) date
FROM n join
ec
ON (n.node_id = ec.node_id_from OR n.node_id = ec.node_id_to) AND
n.date > ec.date
GROUP BY n.node_id;
请注意括号。
如果是这样,您可以将其替换为:
SELECT n.node_id,
MIN(LEAST(n.date, COALESCE(ec.date, n.date), COALECE(ec1.date, n.date)) date
FROM n LEFT JOIN
ec
ON n.node_id = ec.node_id_from AND n.date > ec.date LEFT JOIN
ec ec2
ON n.node_id = ec.node_id_to
GROUP BY n.node_id;