En iyi yaklaşım hakkında bir sorum var. Verilerin boyutu değişken olarak kabul edildiğinde hangi yaklaşımın en iyi olduğuna emin değilim.
Aşağıdaki 3 tabloyu göz önünde bulundurun:
ÇALIŞAN
EMPLOYEE_ID, EMP_NAME
PROJE
PROJECT_ID, PROJ_NAME
EMP_PROJ (yukarıdaki iki tablonun çoğundan çoğuna)
EMPLOYEE_ID, PROJECT_ID
Sorun : Bir Çalışan Kimliği verildiğinde, bu Çalışanın ilişkili olduğu TÜM Projelerin TÜM çalışanlarını bulun.
Bunu iki şekilde denedim. Hangi boyutta veri kullanılırsa kullanılsın her iki yaklaşım da yalnızca birkaç milisaniye kadar farklılık gösterir.
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)
Git
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
Şu an itibariyle her biri 5000 civarında çalışan ve proje bekliyorum. Hangi yaklaşımı önerirsiniz? Teşekkürler!
EDIT: Yaklaşım 1 Uygulama Planı
"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)"
Yaklaşım 2 Uygulama Planı:
"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)"
Yaklaşım 2'nin uygulama planı biraz daha iyi görünüyor, çünkü 'maliyet' yaklaşım 1'in 85'inin aksine 60'tır. Bunu analiz etmenin doğru yolu bu mu?
Bir çok kombinasyonun her türü için bile geçerli olacağını nasıl bilebilir?
explain analyze
planlar arasında daha fazla farklılık ortaya çıkarabilir