ฉันมีคำถามเกี่ยวกับวิธีการที่ดีที่สุด ฉันไม่แน่ใจว่าวิธีใดดีที่สุดเมื่อข้อมูลถูกพิจารณาว่าเป็นขนาด
พิจารณา 3 ตารางต่อไปนี้:
พนักงาน
EMPLOYEE_ID, EMP_NAME
โครงการ
PROJECT_ID, PROJ_NAME
EMP_PROJ (มากไปหามากถึงสองตารางข้างต้น)
EMPLOYEE_ID, PROJECT_ID
ปัญหา : กำหนด EmployeeID ให้ค้นหาพนักงานทั้งหมดของโครงการทั้งหมดที่พนักงานคนนี้มีความเกี่ยวข้อง
ฉันได้ลองทำสองวิธี .. ทั้งสองวิธีต่างกันเพียงไม่กี่มิลลิวินาทีไม่ว่าจะใช้ข้อมูลขนาดใด
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
ณ ตอนนี้ฉันคาดว่าจะมีพนักงานและโครงการประมาณ 5,000 คนต่อคน แต่ไม่มีความคิดเกี่ยวกับความสัมพันธ์ที่หลากหลาย คุณจะแนะนำวิธีใด ขอบคุณ!
แก้ไข: แผนการดำเนินการของแนวทาง 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)"
แผนการดำเนินการของแนวทาง 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)"
ดังนั้นดูเหมือนว่าแผนการดำเนินการของแนวทาง 2 จะดีกว่าเล็กน้อยเนื่องจาก 'ต้นทุน' เท่ากับ 60 เมื่อเทียบกับ 85 วิธี 1 นั่นเป็นวิธีที่ถูกต้องในการวิเคราะห์หรือไม่
เราจะรู้ได้อย่างไรว่ามันจะเป็นจริงแม้แต่กับชุดค่าผสมจำนวนมากทุกประเภท
explain analyze
อาจเปิดเผยความแตกต่างเพิ่มเติมระหว่างแผน