使用INNER JOIN进行SQL查询优化

时间:2017-08-19 02:21:12

标签: sql oracle join optimization

我从学校接受挑战以优化此查询(这是理论问题)

挑战:

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中的最小值。

其次,我使用此查询添加了内部联接。

我的解决方案是否正常或您有更好的选择?

2 个答案:

答案 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;