Được gửi bởi
saly1012
Chào anh chị
em có 3 table như sau
NHANVIEN(manv, hoten, phong)
DEAN(mada,tenda)
PHANCONG(manv, mada, thoigian)
câu hỏi: cho biết tên nhân viên có mada ='DA04'.
Để giải bài này em có 5 cách như sau và tất cả điều cho ra cùng kết quả đúng
--cách 1 và 2 giống hay khác nhau? nếu khác thì cách nào tối ưu hơn?
--cach 1
select tennv
from nhanvien nv, phancong pc
where nv.manv = pc.manv and
mada='DA04'
--cach2
select tennv
from nhanvien nv join phancong pc on nv.manv=pc.manv
where mada ='DA04'
--cach 3
select tennv
from nhanvien
where manv in (select manv
from phancong
where mada ='DA04')
--trong trường hợp dưới đây thì cách 4 và 5 có gì khác ko? nếu khác thì cách nào hay hơn
--cach 4
select tennv
from nhanvien nv JOIN (select manv
from phancong
where mada='DA04') DA04 on nv.manv=DA04.manv
--cach5
select tennv
from nhanvien nv, ( select manv
from phancong
where mada='DA04') DA04
where nv.manv = DA04.manv
==> Anh chị cho em xin lời nhận xét trong từng cách giải
Em cám ơn nhiều ạ!
- Cách 1 và cách 2 là cùng 1 cách nhưng viết theo 2 chuẩn khác nhau (1)
- Cách 4 và cách cũng tương tự, chỉ là 1 cách (2)
Đến đây tập lời giải của bạn thực chất chỉ còn là 3 lời giải (1), (2), và cách 3 (3)
Sau khi xem excution plan ( thực ra điều này cũng chẳng có ý nghĩa gì nếu môi trường test là ảo có vài chục bản ghi) thì đều có cách xử lý như nhau.
Do vậy cả 5 cách trên đều ra kết quả và tốc độ xử lý như nhau.
Trong trường hợp bạn muốn phân tích kĩ hơn thì có thể đọc excution plan thì sẽ thấy. Tôi chưa test với trường hợp của bạn nhưng có thể nói SQL Server sẽ xử lý như thế này trong cả 3 cách giải
1 - Tìm ra rows có mada ='DA04' trong bảng PHANCONG bằng cách sử dụng Index, hoặc Table Scan.
Cách (1) "có thể" thực hiện bước này trước.
Thực ra có thể hiểu bài toán ở đây có 2 phép toán. 1 là Join, 2 là lọc ra các rows có mada ='DA04'.
Thứ tự thực hiện thường sẽ là lọc trước, sau đó Join trong đa số các trường hợp (ngoại lệ nếu có thời gian tôi sẽ trình bày kĩ hơn nhưng chắc chắn nó không phổ biến)
Cách (2) sẽ xử lý bước này đầu tiên do bạn thực hiện 1 bảng có sẵn với 1 bảng chưa xác định, nên nó phải thực hiện bước này để biết là sẽ phải Join với cái gì
Cách (3) cũng vậy do mệnh đề trong IN là chưa rõ ràng. Cần chạy trước để trả về tập giá trị trong IN
2 - Với tập manv thu được từ bước 1, Tiếp tục sử dụng Index hoặc Table Scan để tìm ra rowid tương ứng với manv đó trong bảng NHANVIEN
3 - Với rowid tương ứng đó, lookup lại bảng NHANVIEN (Lookup chỉ khi bạn có Index) để lấy ra tên nhân viên
Như vậy cả 3 cách trên đều có cách xử lý như nhau trong đa số trường hợp, chỉ là cách viết có khác nhau Một số trường hợp đặc biệt có thể xảy ra khiến cho cách (1) có thể có execution plan khác với 2 cách trên nhưng cũng không thể đánh giá là nó tốt hơn hay tồi hơn nếu không đưa dữ liệu cụ thể.
Thân
Oracle DBA - Hướng dẫn Oracle HCM Y!M red_devilic
Bookmarks