Inner Join vs Exists() 同时避免重复行

Posted

技术标签:

【中文标题】Inner Join vs Exists() 同时避免重复行【英文标题】:Inner Join versus Exists() while avoiding duplicate rows 【发布时间】:2013-02-18 17:29:47 【问题描述】:

这是一个复杂的问题,所以在我设置场景时请耐心等待:

假设我们有一个简化的表格设置,如下所示:

table 1(employee): 
   employee_id, -primary key
   first_name,
   last_name,
   days_of_employment

with data:
employee_id  first_name last_name days_of_employment
111          Jack       Stevens   543
222          Clarice    Bobber    323
333          Roy        Cook      736
444          Fred       Roberts   1000
...

table 2(teams): 
   team_code, --primary key
   description

with data:
team_code description
ERA       Enrollment Records Assoc.
RR        Rolling Runners
FR        French Revolution
...

table 3(employees_teams):
   employee_id, --primary key
   team_code --primary key

with data:
employee_id team_code
111         RR
111         FR
222         FR
222         ERA
333         FR
...

我希望这些表格能够清楚地说明它们是什么以及它们的用途。这是我的需求场景:“我想要 Rolling Runners and Enrollment Records Assoc. 团队中员工的平均就业天数。”我知道如何编写此查询有两种方法,它们似乎都运行良好,但我真正想知道的是哪一种方法对 oracle 数据库的处理速度更快。请记住,这些查询的编写方式是为了避免产生重复的行,这会破坏平均计算:

查询 1:

SELECT AVG(e.days_of_employment) avg_days_of_employment
FROM   employee e,
       (
        SELECT DISTINCT employee_id
        FROM   employees_teams
        WHERE  team_code IN ('ERA','RR')) available_employees
WHERE  e.employee_id = available_employees.employee_id

查询 2:

SELECT AVG(e.days_of_employment) avg_days_of_employment
FROM   employee e
WHERE  EXISTS(
    SELECT 1
    FROM   employees_teams et
    WHERE  et.team_code IN ('ERA','RR')
      AND  et.employee_id = e.employee_id)

我提供的这个示例数据可能一开始可能没有意义,但我仍然想知道哪个查询“更好”使用。

【问题讨论】:

【参考方案1】:

我会说使用 EXISTS 方法,因为除了检查是否存在之外,您实际上并不需要 available_employees 提供的任何东西。 话虽如此,这也取决于您的数据以及您的数据库查询优化器如何优化它。我建议您查看每种方法的查询计划,看看哪种方法更便宜。

也检查这些链接http://dotnetvj.blogspot.com/2009/07/why-we-should-use-exists-instead-of.htmlCan an INNER JOIN offer better performance than EXISTS

【讨论】:

虽然您提供的第二个链接中的问题不一定相同,但接受的答案确实回答了我的问题。谢谢。

以上是关于Inner Join vs Exists() 同时避免重复行的主要内容,如果未能解决你的问题,请参考以下文章

使用 INNER JOIN 和 NOT EXISTS 访问 INSERT 语句给出错误结果

使用 INNER JOIN 或 EXISTS 在 m2m 关系中查找属于多个是不是更好?

INEXISTS的相关子查询用INNER JOIN 代替--性能优化

Laravel Eloquent Join vs Inner Join?

SQL Left/Inner/Normal Join vs Where while 条件语句

MAX with Inner join VS rank() over