C. Các bớc tối u hoá
1. Định giá biểu thức hoặc điều kiện
1.1. Chuyển thành các hằng số (Consts)
Bằng cách định giá các biểu thức thành hằng số một cách tối đa thì câu lệnh SQL sẽ đợc thực hiện nhanh hơn. Điều này là hiển nhiên bởi vì nếu định giá một biểu thức thì chỉ làm có một lần trong khi nếu câu lệnh cũ thì biểu thức đó sẽ đợc thực hiện trong suốt quá trình duyệt. Ví dụ sau sẽ làm rõ điều này. Giả sử cần đa ra TênNhânViên của những ngời có Lơng>2000$ trong bảng NhânViên, có thể thực hiện một trong ba câu lệnh sau:
SELECT TênNhânViên, Lơng FROM NhânViên WHERE Lơng>20,000/10; SELECT TênNhânViên, Lơng FROM NhânViên WHERE Lơng>2,000; SELECT TênNhânViên, Lơng FROM NhânViên WHERE Lơng*10>20,000;
Rõ ràng cả ba câu lệnh đều trả lại cùng một kết quả tuy nhiên câu lệnh thứ nhất và thứ ba phải thêm một phép tính để ứng với mỗi phép so sánh so với câu lệnh thứ hai. Oracle sẽ tự động chuyển câu lệnh thứ nhất trở thành câu lệnh thứ hai còn câu lệnh thứ ba thì không đơn giản đối với Oracle để thành câu lệnh thứ hai. Chính vì lý do này mà những ngời phát triển phần mềm nên tự chuyển điều kiện so sánh thành dạng một cột với một hằng số trong bất kì trờng hợp nào có thể hơn là một điều kiện trong đó có chứa một biểu thức với một cột.
Oracle sẽ chuyển các điều kiện đơn giản sử dụng toán tử so sánh LIKE không sử dụng kí tự đại diện thành một biểu thức so sánh bằng. Ví dụ, Oracle sẽ chuyển biểu thức thứ nhất thành biểu thức thứ hai:
Chuyển biểu thức: TênNhânViên LIKE 'SMITH' thành biểu thức tơng đơng: TênNhânViên = 'SMITH'
Các biểu thức kiểu này chỉ đợc chuyển khi mà biểu thức so sánh với các biến có kích thớc (size) không cố định. Nếu nh TênNhânViên có kiểu CHAR(10) thì biểu thức trên không đợc chuyển vì TênNhânViên có kích thớc cố định.
1.3. Toán tử IN
Oracle sẽ chuyển các biểu thức có chứa toán tử so sánh IN thành các điều kiện so sánh bằng liên kết với nhau bởi toán tử logic OR.
Ví dụ:
Chuyển biểu thức: TênNhânViên IN ('SMITH','KING','JONES')
thành: TênNhânViên='SMITH' OR TênNhânViên='KING' OR TênNhânViên='JONES'
1.4. Toán tử ANY hoặc SOME
Các biểu thức điều kiện sẽ đợc chuyển thành các điều kiện so sánh liên kết với nhau bởi toán tử OR. Các điều kiện sử dụng ANY hoặc SOME kèm theo một subquery sẽ chuyển thành toán tử EXITST và một query liên quan.
Ví dụ:
Chuyển biểu thức: Lơng> ANY (:Lơng1, :Lơng2) thành biểu thức: Lơng>:Lơng1 OR Lơng>:Lơng2
và chuyển: x> ANY (SELECT Lơng FROM NhânViên WHERE Nghề='Phân tích viên') thành biểu thức tơng đơng là:
EXITST (SELECT Lơng FROM NhânViên WHERE Nghề='Phân tích viên' and x>Lơng)
1.5. Toán tử ALL
Oracle sẽ chuyển các điều kiện sử dụng toán tử ALL thành các điều kiện so sánh bằng liên kết với nhau qua toán tử AND. Nếu điều kiện kèm theo subquery thì sẽ chuyển thành subquery vào trong một điều kiện mà sử dụng toán tử ANY và một query cơ bản.
thành Lơng> :Lơng1 AND Lơng > :Lơng2
Từ x>ALL ( SELECT Lơng FROM NhânViên WHERE M Phòng=10;ã
thành NOT (x<= ANY ( SELECT Lơng FROM NhânViên WHERE M Phòng=10))ã
và sau đó sẽ sử dụng luật áp dụng với toán tử ANY thành câu lệnh sau: NOT EXISTS ( SELECT Lơng FROM NhânViên WHERE M Phòng=10 AND x<= Lã ơng)
1.6. Toán tử BETWEEN
Oracle sẽ luôn chuyển điều kiện sử dụng toán tử BETWEEN thành điều kiện sử dụng toán tử >= và <= liên kết bởi toán tử AND.
Ví dụ:
Chuyển biểu thức: Lơng BETWEEN 2,000 AND 3,000
thành biểu thức: Lơng>=2,000 AND Lơng<=3,000
1.7. Toán tử NOT
Oracle sẽ luôn chuyển điều kiện có toán tử NOT thành một điều kiện đối với nó. Ví dụ: Chuyển biểu thức:
NOT M Phòng = ( SELECT M Phòng FROM NhânViên WHERE TênNhânViên='TAYLOR')ã ã
thành biểu thức tơng đơng:
M Phòng <> ( SELECT M Phòng FROM NhânViên WHERE TênNhânViên='TAYLOR')ã ã
Thông thờng một điều kiện có chứa toán tử NOT thờng có nhiều cách viết.
Oracle chấp nhận việc chuyển đổi những điều kiện nh vậy thành những điều kiện phủ định thành phần, thậm chí ngay cả việc kết quả có chứa nhiều NOT hơn.
Ví dụ các biểu thức sau chứa toán tử NOT có nghĩa tơng đơng: NOT ( Lơng<1,000 OR Thởng IS NULL)
NOT Lơng<1,000 AND Thởng IS NOT NULL Lơng>=1,000 AND Thởng IS NOT NULL
1.8. Chuyển tiếp
Nếu hai điều kiện trong cùng một mệnh đề WHERE có sử dụng một cột chung thì Oracle đôi khi có thể chuyển thành giá trị cơ bản. Điều này có khả năng làm cho truy nhập bằng Index có thể sử dụng trong câu lệnh mới nhng lại không sử dụng đợc trong câu lệnh cũ.
Các điều kiện đó có dạng: WHERE Cột1 <toán tử> <hằng số> AND Cột1=Cột2 đợc chuyển thành: WHERE Cột1 <toán tử> <hằng số> AND Cột2 <toán tử> <hằng số> Trong đó <toán tử > có thể là: =,!=, ^=, <, <>, >,<=, >=.
Hằng số là bất kì giá trị hằng nào với toán tử, hàm SQL, kí tự, biến kết hợp hoặc biến.
Ví dụ câu lệnh:
SELECT * FROM NhânViên, Phòng
WHERE NhânViên.M Phòng=20 AND NhânViên.M Phòng=Phòng.M Phòngã ã ã
đợc chuyển thành câu lệnh có nghĩa tơng đơng: SELECT * FROM NhânViên, Phòng
WHERE NhânViên.M Phòng=20 AND Phòng.M Phòng=20;ã ã
Chú ý rằng dạng điều kiện sau sẽ không đợc chuyển:
WHERE Cột1 <toán tử> Cột3 AND Cột1=Cột2 thành điều kiện Cột2 <toán tử> Cột3. Cách thức này cũng chỉ đợc dùng trong tối u dựa vào luật Cost-based.