gpt4 book ai didi

sql - 我应该使用 SQL JOIN 还是 IN 子句?

转载 作者:行者123 更新时间:2023-12-01 12:59:00 25 4
gpt4 key购买 nike

我对最佳方法有疑问。当数据大小可变时,我不确定哪种方法最好。

考虑以下 3 个表:

员工

EMPLOYEE_ID,EMP_NAME

项目

PROJECT_ID,PROJ_NAME

EMP_PROJ(以上两个表的多对多)

EMPLOYEE_ID,PROJECT_ID

问题:给定一个 EmployeeID,找到与该 Employee 关联的所有项目的所有员工。

我已经尝试过两种方法。无论使用多大的数据,这两种方法都只相差几毫秒。

SELECT EMP_NAME FROM EMPLOYEE
WHERE EMPLOYEE_ID IN (
SELECT EMPLOYEE_ID FROM EMP_PROJ
WHERE PROJECT_ID IN (
SELECT PROJECT_ID FROM EMP_PROJ p, EMPLOYEE e
WHERE p.EMPLOYEE_ID = E.EMPLOYEE_ID
AND E.EMPLOYEE_ID = 123)

select c.EMP_NAME FROM
(SELECT PROJECT_ID FROM EMP_PROJ
WHERE EMPLOYEE_ID = 123) a
JOIN
EMP_PROJ b
ON a.PROJECT_ID = b.PROJECT_ID
JOIN
EMPLOYEE c
ON b.EMPLOYEE_ID = c.EMPLOYEE_ID

截至目前,我预计每个员工和项目大约有 5000 名......但不知道存在什么样的多对多关系。你会推荐哪种方法?谢谢!

编辑:方法一的执行计划

"Hash Join  (cost=86.55..106.11 rows=200 width=98)"
" Hash Cond: (employee.employee_id = emp_proj.employee_id)"
" -> Seq Scan on employee (cost=0.00..16.10 rows=610 width=102)"
" -> Hash (cost=85.07..85.07 rows=118 width=4)"
" -> HashAggregate (cost=83.89..85.07 rows=118 width=4)"
" -> Hash Semi Join (cost=45.27..83.60 rows=118 width=4)"
" Hash Cond: (emp_proj.project_id = p.project_id)"
" -> Seq Scan on emp_proj (cost=0.00..31.40 rows=2140 width=8)"
" -> Hash (cost=45.13..45.13 rows=11 width=4)"
" -> Nested Loop (cost=0.00..45.13 rows=11 width=4)"
" -> Index Scan using employee_pkey on employee e (cost=0.00..8.27 rows=1 width=4)"
" Index Cond: (employee_id = 123)"
" -> Seq Scan on emp_proj p (cost=0.00..36.75 rows=11 width=8)"
" Filter: (p.employee_id = 123)"

方法二的执行计划:

"Nested Loop  (cost=60.61..112.29 rows=118 width=98)"
" -> Index Scan using employee_pkey on employee e (cost=0.00..8.27 rows=1 width=4)"
" Index Cond: (employee_id = 123)"
" -> Hash Join (cost=60.61..102.84 rows=118 width=102)"
" Hash Cond: (b.employee_id = c.employee_id)"
" -> Hash Join (cost=36.89..77.49 rows=118 width=8)"
" Hash Cond: (b.project_id = p.project_id)"
" -> Seq Scan on emp_proj b (cost=0.00..31.40 rows=2140 width=8)"
" -> Hash (cost=36.75..36.75 rows=11 width=8)"
" -> Seq Scan on emp_proj p (cost=0.00..36.75 rows=11 width=8)"
" Filter: (employee_id = 123)"
" -> Hash (cost=16.10..16.10 rows=610 width=102)"
" -> Seq Scan on employee c (cost=0.00..16.10 rows=610 width=102)"

所以看起来方法 2 的执行计划稍微好一些,因为“成本”是 60 而不是方法 1 的 85。这是分析这个的正确方法吗?

如何知道它是否适用于各种多对多组合?

最佳答案

这两种方法都可能导致性能欠佳,因为它们都使用根据 DBMS 是否有效优化的子查询。

我建议避免子查询并使用 JOIN 来表示要使用的内容,例如:

编辑:

我更正并简化了我的示例:

select coll.EMP_NAME
from EMP_PROJ ep1
inner join EMP_PROJ ep2 on ep1.PROJECT_ID = ep2.PROJECT_ID
inner join EMPLOYEE coll on ep2.EMPLOYEE_ID = coll.EMPLOYEE_ID
where ep1.EMPLOYEE_ID = 123

我认为应该注意,在一个查询中使用不同 别名多次引用同一个 表是完全合法的。对于查询来说,这在逻辑上“看起来”像两个单独的表,它们恰好具有相同的结构和数据。

关于sql - 我应该使用 SQL JOIN 还是 IN 子句?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7936690/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com