Eu tenho uma pergunta sobre a melhor abordagem. Não tenho certeza de qual abordagem é melhor quando os dados são considerados variáveis em tamanho.
Considere as 3 TABELAS a seguir:
EMPREGADO
EMPLOYEE_ID, EMP_NAME
PROJETO
PROJECT_ID, PROJ_NAME
EMP_PROJ (muitas para muitas das duas tabelas acima)
EMPLOYEE_ID, PROJECT_ID
Problema : Dado um CódigoDoEmpregado, localize TODOS os funcionários de TODOS os Projetos aos quais este Funcionário está associado.
Eu tentei isso de duas maneiras. Ambas as abordagens diferem apenas em alguns milissegundos, independentemente do tamanho dos dados usados.
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)
ir
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
A partir de agora, espero cerca de 5000 funcionários e projetos cada .. mas não tenho idéia sobre o tipo de relação entre muitos e muitos. Qual abordagem você recomendaria? obrigado!
EDIT: Plano de Execução da Abordagem 1
"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)"
Plano de execução da abordagem 2:
"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)"
Parece que o plano de execução da Abordagem 2 é um pouco melhor, porque o 'custo' é 60 em oposição a 85 da abordagem 1. É o caminho certo para analisar isso?
Como alguém sabe que isso se aplica mesmo para todo tipo de combinação de muitas e muitas?
explain analyze
pode revelar mais diferenças entre os planos