Tengo una pregunta sobre el mejor enfoque. No estoy seguro de qué enfoque es mejor cuando los datos se consideran de tamaño variable.
Considere las siguientes 3 TABLAS:
EMPLEADO
EMPLOYEE_ID, EMP_NAME
PROYECTO
PROJECT_ID, PROJ_NAME
EMP_PROJ (muchas a muchas de las dos tablas anteriores)
EMPLOYEE_ID, PROJECT_ID
Problema : dado un Id. De empleado, encuentre TODOS los empleados de TODOS los proyectos con los que este empleado esté asociado.
He intentado esto de dos maneras ... ambos enfoques difieren solo en unos pocos milisegundos, sin importar el tamaño de los datos que se utilicen.
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)
Vamos
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 ahora, espero alrededor de 5000 empleados y proyectos cada uno ... pero no tengo idea de qué tipo de relación existe. ¿Qué enfoque recomendarías? ¡Gracias!
EDITAR: Plan de Ejecución del Enfoque 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)"
Plan de Ejecución del Enfoque 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 el plan de Ejecución del Enfoque 2 es ligeramente mejor, porque el "costo" es 60 en lugar del 85 del enfoque 1. ¿Es esa la forma correcta de analizar esto?
¿Cómo se sabe que será válido incluso para todo tipo de combinaciones de muchos?
explain analyze
podría revelar más diferencias entre los planes