|
||||||||||||||||||||||
Tối ưu câu lệnh Oracle SQL – phần 1: nền tảng cơ bảnTối ưu câu lệnh là chủ đề nâng cao, vì vậy để có thể hiểu được các kỹ thuật tối ưu câu lệnh Oracle SQL, chúng ta cần tìm hiểu một số khái niệm cơ bản liên quan đến lĩnh vực này, bài viết này không nhằm mục đích chuyển tải toàn bộ kiến thức liên quan đến tối ưu câu lệnh SQL, bài viết chỉ trình bày những khái niệm quan trọng nhất, đủ giúp những đọc giả đã am hiểu kiến trúc Oracle có thể hiểu được. Nền tảng cơ bảnTrình tự xử lý câu lệnh SQLOracle Server xử lý câu lệnh SQL theo trình tự các bước sau:
Trong các giai đoạn xử lý trên, giai đoạn Parse chiếm nhiều thời gian nhất. Công cụ tối ưu câu lệnh SQL*Plus AUTOTRACEChức năngThu thập thông tin mô tả quá trình thực thi câu lệnh SQL, thường được dùng để tối ưu câu lệnh. Cài đặtĐể sử dụng đầy đủ chức năng của công cụ này, cần tạo Table tên PLAN_TABLE và gán nhóm quyền PLUSTRACE cho tài khoản muốn sử dụng công cụ:
Ví dụ
Quan sát kết quả từ mã dẫn trên, ta thấy công cụ AUTOTRACE gửi về ba nhóm thông tin sau:
Cách sử dụng
Sơ đồ thực thi câu lệnh SQLSơ đồ thực thi câu lệnh SQL (Execution Plan - EP) mô tả thứ tự các bước Oracle cần thực thi để có được kết quả câu lệnh nhanh nhất. Ví dụ về EP của câu lệnh xem dữ liệu trên hai Table CUSTOMERS và COUNTRIES: Oracle qui định thứ tự xử lý các bước của EP như sau:
Như vậy, ta thấy EP trên được xử lý theo thứ tự được đánh số bên phải. Một EP đầy đủ bao gồm ba thành tố sau: phương thức truy cập dữ liệu, phương pháp JOIN và thứ tự JOIN giữa hai hay nhiều tập dữ liệu. Phương thức truy cập dữ liệuXác định cách thức truy cập vật lý đến từng dòng dữ liệu của Table, ví du một số phương pháp truy cập dữ liệu Table phổ biến:
Với cách này, ta thấy để đọc được một dòng dữ liệu của Table thì phải tốn ít nhất hai thao tác IO; một thao tác IO đọc trên cây Index và một thao tác IO đọc trên Table. Theo luật chung thì cách này thích hợp khi kết quả dữ liệu cần tìm ít hơn 5% khối lượng dữ liệu của Table. Phương pháp JOINXác định phương pháp kết hợp dữ liệu giữa hai hay nhiều Table với nhau, ví dụ về phương pháp JOIN giữa hai Table T1 và T2:
Thứ tự JOINXác định thứ tự JOIN khi câu lệnh SQL có nhiều hơn hai Table kết hợp với nhau, thứ tự JOIN hợp lý giúp giảm thiểu dữ liệu cần kết hợp với nhau mà vẫn đạt được kết quả đúng. Sau khi tìm hiểu qua các khái niệm cơ bản, chúng ta thử quay lại tìm hiểu ý nghĩa EP của câu lệnh SQL trên:
Đến đây có thể các bạn thắc mắc là tại sao Oracle lại chọn phương pháp Join là NESTED LOOP ? tại sao CUSTOMERS lại được chọn làm outer-table ?, quyết định chọn này được thực hiện bởi Trình tối ưu câu lệnh Oracle. Trình tối ưu câu lệnh OracleTrình tối ưu giúp Oracle xác định được một EP tốt nhất cho một câu lệnh SQL. Trình tối ưu Oracle 9i hỗ trợ phương pháp tối ưu dựa vào cú pháp lệnh (Rule Based Optimizer – RBO) và phương pháp tối ưu dựa vào chi phí ước tính cần dùng để thực thi câu lệnh (Cost Based Optimizer – CBO). Mặc định Oracle9i dùng RBO. RBORBO có từ phiên bản Oracle6, dựa vào cấu trúc câu lệnh SQL để xác định EP tốt nhất. RBO sử dụng một lược đồ phân hạng các phương thức truy cập dữ liệu để chọn phương thức truy cập cho EP, phương thức nào có số hạng thấp sẽ được ưu tiên chọn. Lược đồ phân hạng các phương thức truy cập dữ liệu được qui định như sau:
Ta thấy truy cập theo ROWID có số hạng thấp nhất là 1; nghĩa là phương thức truy cập đến dữ liệu nhanh nhất, và truy cập theo Index có số hạng là 4 sẽ nhanh hơn nhiều so với truy cập theo Full-Table-Scan có số hạng cao nhất là 15. Ví dụ sau cho thấy RBO sử dụng luật phân hạng để chọn phương thức truy cập dữ liệu cho EP. Do cột CUST_ID của điều kiện WHERE có UNIQUE INDEX lên RBO chọn phương thức truy cập theo Index: SQL> DROP TABLE new_table;
Table dropped.
SQL> CREATE TABLE new_table AS SELECT object_id, object_name, object_type FROM all_objects WHERE rownum <= 5000; 2 3 4
Table created.
SQL> SET AUTOTRACE TRACEONLY EXPLAIN SQL> SELECT * FROM new_table WHERE object_type = 'TABLE';
Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (FULL) OF 'NEW_TABLE'
SQL> SET AUTOTRACE OFF
SQL> CREATE INDEX idx_object_type ON new_table(object_type);
Index created.
SQL> SET AUTOTRACE TRACEONLY EXPLAIN SQL> SELECT * FROM new_table WHERE object_type = 'TABLE';
Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE 1 0 TABLE ACCESS (BY INDEX ROWID) OF 'NEW_TABLE' 2 1 INDEX (RANGE SCAN) OF 'IDX_OBJECT_TYPE' (NON-UNIQUE) CBOCBO có từ phiên bản Oracle7, CBO dựa vào “thông tin tổng hợp” được để ước tính chi phí của EP, EP tốt nhất là EP có chi phí ước tính nhỏ nhất. Oracle9i chỉ dùng CBO để tối ưu nếu đối tượng tham chiếu đến có thông tin mô tả. “Thông tin tổng hợp” trong ngữ cảnh này bao gồm:
Nếu cung cấp đầy đủ và chính xác các thông tin trên, trình tối ưu CBO có thể xác định được một EP tốt nhất. Tiếp theo ví dụ trong phần RBO, chúng ta dùng lệnh ANALYZE TABLE để thu thập thông tin của NEW_TABLE cho trình tối ưu: SQL> SET AUTOTRACE OFF SQL> @li NEW_TABLE
indexes on table NEW_TABLE%:
TABLE_NAME INDEX_TYPE INDEX_NAME -------------------- ---------- ------------------------------ NEW_TABLE NONUNIQUE IDX_OBJECT_TYPE
SQL> ANALYZE TABLE new_table COMPUTE STATISTICS;
Table analyzed.
SQL> SET AUTOTRACE TRACEONLY EXPLAIN SQL>SELECT * FROM new_table WHERE object_type = 'TABLE';
Execution Plan ---------------------------------------------------------- 0 SELECT STATEMENT Optimizer=CHOOSE (Cost=5 Card=2500 Bytes=107500) 1 0 TABLE ACCESS (FULL) OF 'NEW_TABLE' (Cost=5 Card=2500 Bytes=107500)
Ta thấy kết quả của EP có một số điểm khác biệt so với thời điểm trước khi thu thập thông tin:
Phụ lụcGiải nghĩa từBind-variable: kỹ thuật viết mã không gán giá trị cố định, kỹ thuật này giúp tăng tính sẵn sàng, hiệu năng và bảo mật cho hệ thống Oracle. Ví dụ: Mã không dùng Bind-Variable BEGIN UPDATE employees SET SALARY=SALARY + 100 WHERE employee_id = 100; END; Mã dùng Bind-Variable DECLARE bind_var NUMBER := 100; BEGIN UPDATE employees SET SALARY=SALARY + 100 WHERE employee_id = bind_var; END; Outer-table: từng dòng dữ liệu của Table này sẽ đối sánh với tất cả dòng của inner-table, còn gọi là driving-table, được đề cập đến trong phương pháp NESTED LOOP JOIN, thường đi chung với thuật ngữ inner-table Inner-table: tất cả dòng dữ liệu của Table này sẽ được đối sánh với từng dòng của outer-table. Mã lệnhMột số File mã lệnh tiện ích sử dụng trong bài viết:
Lịch sử thay đổi
Tham khảo
Mời các bạn đọc phần tiếp theo của chủ đề này: Phần 2 – Tối ưu câu lệnh SQL có Table và có một điều kiện
Để hiểu rõ hơn về chủ đề này, các bạn có thể tham gia các khóa học sau tại tại Trung tâm VietPace:
|
||||||||||||||||||||||
|
Copyright 2009 www.vietpace.com, All rights reserved. |