D. Kết luận về phơng pháp tối u trong Oracle
1. Tối u bằng việc thay đổi các thực thể
Bớc này đợc thực hiện trong giai đoạn thiết kế phần mềm và việc thay đổi các thực thể chỉ đợc sử dụng trong các trờng hợp đặc biệt khi việc thiết kế các bảng dẫn đến câu lệnh thực hiện trên đó phải sử dụng đến nhiều bảng trung gian.
Bảng 1 Bảng 2 Bảng i Bảng n
Bằng việc thêm vào một thuộc tính từ bảng thứ n vào bảng thứ nhất có thể tạo ra một liên kết trực tiếp giữa bảng 1 và bảng n mà không cần phải truy xuất các bảng trung gian. Khi thay đổi lại cấu trúc các bảng thì sẽ phá vỡ dạng chuẩn dữ liệu 3NF nhng câu lệnh truy xuất trên các bảng sẽ nhanh hơn. Do đó thao tác cấu trúc lại các bảng đòi hỏi ngời thiết kế phải nắm vững các qui tắc về nghiệp vụ cũng nh phải lờng trớc đợc các vấn đề nảy sinh trong các thao tác cập nhật dữ liệu.
Để biết đợc khách hàng thuộc chi nhánh nào của công ty có hai cách thực hiện nh sau:
Cách 1: Phải thực hiện kết nối các bảng CUSTOMERS (khách hàng), STREETS
(đờng, phố), WARDS (phờng), SUBAREA (tiểu khu), DISTRICTS (quận), BRANCH (chi nhánh) sau đó thực hiện phép chiếu trên cột BRANCH.name.
Cách 2: Thêm cột branch_code vào bảng CUSTOMERS. Chỉ cần thực hiện kết nối giữa hai bảng CUSTOMERS và BRANCH sau đó chiếu trên cột BRANCH.name.
STREETS # * ID * WAR_ID * STREET_CODE * NAME o CREATED_BY o CREATED_ON o MODIFIED_BY o MODIFIED_ON o DETAIL BRANCH (#) # * ID * BRANCH_CODE * NAME o CREATED_BY o MODIFIED_BY o CREATED_ON o MODIFIED_ON DISTRICTS (#) # * ID * BRN_ID * DIST_CODE * NAME o CREATED_BY o MODIFIED_BY o CREATED_ON o MODIFIED_ON SUBAREA # * ID * DIS_ID * AREA_CODE * NAME o CREATED_BY o MODIFIED_BY o CREATED_ON o MODIFIED_ON WARDS (#) # * ID * SUA_ID * WARD_CODE * NAME o CREATED_BY o MODIFIED_BY o CREATED_ON o MODIFIED_ON CUSTOMERS # * ID * CUSTOMER_NO * CONTRACT_NO * STATUS * NAME * ADDRESS o TELFAX o IDCARD_NO o SORT_NAME * INST_ADDRESS * STREET_ID * WARD_CODE * AREA_CODE * DIST_CODE * BRANCH_CODE * HOUSE_NUM o PERSON_NUM * CCAT_ID o CURRENCY_ID o USAGE_LIST o TOTAL_QUOTA * PAYMENT_TYPE o BANK_ACCOUNT o BANK_OWNER o BANK_NAME * CONTRACT_DATE o WSC_SIGNEDBY * CP_CODE o CREATED_BY o CREATED_ON o MODIFIED_BY o MODIFIED_ON o INACTIVE_BY o INACTIVE_ON o REACTIVE_BY o REACTIVE_ON WAR_SUA_FK SUA_DIS_FK DIS_BRN_FK CUST_STR_FK STR_WAR_FK CUST_BRN_FK
2. Tối u các Table space
Bớc này đợc thực hiện trong quá trình tạo thiết kế phần mềm. Lý do sử dụng việc phân bố các thực thể vào các Table là CSDL trong Oracle đợc tạo nên từ các Tablespace, bằng việc sắp xếp các bảng trong các Tablespace hợp lý cũng có thể tăng đáng kể tốc độ thực hiện câu lệnh. Với các bảng ít cập nhật dữ liệu thì nên để trong một Tablespace (nh bảng chứa thông tin về khách hàng) và các bảng hay cập nhật vào các Tablespace khác (nh bảng hoá đơn xuất kho). Mặt khác các Tablespace có thể đặt trên các đĩa khác nhau do vậy việc truy xuất đến các Tablespace có thể thực hiện một cách đồng thời (do I/O không cần sự điều khiển của CPU). Oracle đã khuyến cáo nên tạo một Tablespace chỉ để chứa các Index và tốt nhất là đặt trên một ổ đĩa khác với các Tablespace chứa dữ liệu. Điều này có thể tăng tốc độ thực hiện truy xuất CSDL và còn một lý do nữa là nếu Tablespace chứa Index bị mất thì có thể dễ dàng tạo lại.
Ví dụ trong hệ quản lý hoá đơn nớc có 8 Table space đợc tạo nh sau:
Tablespace USERS chứa các đối tợng của ngời dùng nằm trong Data File Usr1BRN.ora và kích thớc là 100M.
Tablespace TEMP là vùng chứa các thông tin tạm nằm trong Data File Tmp1BRN.ora' size 80M;
Tablespace RBS dùng để chứa các Rollback segment nằm trong data File Rbs1BRN.ora' kích thớc 60M;
Tablespace INDEXES chứa các Index nằm trong Data File Ind1BRN.ora kích thớc 100M;
Tablespace CUST chứa các bảng ít thay đổi về khách hàng và thông tin liên quan nằm trong Data File Cus1BRN.ora kích thớc 50M;
Tablespace BILL chứa các bảng hoá đơn hay thay đổi nằm trong Data File Bil1BRN.ora kích thớc 50M;
Tablespace USAGE chứa các thông tin về loại hình sử dụng nằm trong Data File Usg1BRN.ora kích thớc 50M;
Tablespace METER chứa các thông tin về đồng hồ nằm trong Data File Met1BRN.ora kích thớc 50M;
3. Tối u vùng nhớ hệ thống SGA
Khi Oracle hoạt động thì mọi thông tin phải chứa trong bộ nhớ hoặc đĩa. Do việc truy xuất trên RAM sẽ nhanh hơn nhiều với việc truy xuất trên đĩa cho nên
một trong những thao tác cơ bản trong tối u để hệ thống có thể hoạt động hiệu quả hơn bằng việc thay đổi các tham số của vùng nhớ SGA (các tham số nằm trong Init File, có thể tìm thấy file này ở th mục DATABASE). Chú ý rằng nên cấu hình làm sao để cho toàn bộ vùng nhớ SGA nằm trong Physical Memory là tốt nhất. Có thể thay đổi kích thớc của SGA thông qua việc thay đổi từng thành phần của SGA và độ lớn của SGA chính là tổng độ lớn của ba thành phần Share Pool + Buffer Cache + Redo Log Buffer.
Database Buffer Cache
Vùng nhớ hệ thống SGA
SGA
Shared Pool RedoLog
Buffer Data Buffer Cache
• Điều chỉnh kích thớc Share Pool qua thông số shared_pool_size ở trong Parameter File. Trong Share Pool có ba thành phần là Library cache, Data dictionary cache và Session information. Kích thớc của Share Pool là thích hợp khi nó thoả mãn các điều kiện dới đây.
- Với độ lớn Library cache thích hợp khi mà tỉ lệ số lần thủ tục và hàm trong th viện đợc thực hiện (PINS) chia cho số lần hàm và thủ tục đó phải nạp từ đĩa (RELOADS). Tỉ lệ này nhỏ hơn hoặc bằng 1% và càng gần 0 càng tốt. Để biết đợc tỉ lệ này cần thực hiện câu lệnh sau:
SELECT (sum(reloads)/sum(pins))*100,’%’ FROM v$librarycache;
Kết quả thực hiện với Database Center 0.09366945%, nh vậy bộ nhớ dành cho Library Cache khá nhiều.
- Độ lớn của Data dictionary cache thích hợp khi tỉ lệ số lần lấy thông tin (GETS) chia cho số lần thông tin không có (GETMISSES) nằm trong khoảng 10% đến 15% và càng gần 0 càng tốt. Giá trị này đợc biết qua câu lệnh sau:
SELECT (SUM(GETMISSES)/SUM(GETS))*100,'%' FROM V$ROWCACHE;
Kết quả thực hiện với Database Center là 2.0352019%, nh vậy vùng bộ nhớ dành cho Data dictionary cache khá nhiều.
• Điều chỉnh độ lớn của Database Bufer Cache: Thành phần này đợc Oracle chia làm nhiều Block mỗi Block có kích thớc cố định tuỳ thuộc hệ điều hành và xác định qua tham số db_block_size trong Parameter File. Bằng cách thay đổi số Block (qua tham số db_block_buffers) sẽ thay đổi đợc kích thớc của Database Bufer Cache.
Độ lớn của Database Bufer Cache thích hợp khi tỉ lệ số khối dữ liệu đợc đọc từ đĩa (physical reads) chia cho tổng số các khối đợc yêu cầu (db block gets + constent gets). Tỉ lệ này nên nhỏ hơn 30% đến 40% và càng gần 0 càng tốt. Có thể xác định đợc tỉ lệ này qua các câu lệnh sau.
CREATE TABLE kq (ratio number); DECLARE p NUMBER; d NUMBER; c NUMBER; r NUMBER; BEGIN
SELECT value INTO p FROM v$sysstat WHERE name='physical reads'; SELECT value INTO d FROM v$sysstat WHERE name='db block gets'; SELECT value INTO c FROM v$sysstat WHERE name='consistent gets'; r := p/(d+c);
r := r*100;
INSERT INTO kq VALUES (r); EXCEPTION
WHEN ZERO_DIVIDE THEN INSERT INTO kq VALUES (0); END;
/
SELECT ratio,'%' FROM kq; DROP TABLE kq;
Kết quả thực hiện Database Center là 64.517194 %, điều này chứng tỏ vùng bộ nhớ dành cho Database Bufer Cache đủ tốt và nên dành thêm vùng bộ nhớ từ Share Pool sang.
• Kích thớc của Redo Log Buffer có thể điều chỉnh đợc bằng tham số log_buffer trong Parameter File.
4. Tối u hoá sử dụng Index
Việc Index giúp tăng tốc độ truy nhập tới bảng tuy nhiên nó lại giảm tốc độ của quá trình thêm, cập nhật dữ liệu. Nói chung nên tạo Index khi dữ liệu của cột có tính chọn lọc cao (giá trị trùng lặp) không nhiều và Index đặc biệt hữu ích khi mà số lợng hàng tìm đợc là 2% - 4% so với số lợng hàng của bảng. Khi số lợng các hàng trả lại là nhiều thì bản thân việc truy nhập trên B-tree cũng mất khá nhiều thời
gian vì vậy lúc đó dùng phơng pháp duyệt toàn bộ có thể lại nhanh hơn. Không nên tạo Index cho các cột chứa quá ít giá trị khác nhau nh YES và NO, tuy nhiên nếu các câu lệnh thờng xuyên làm việc với một giá trị trị giả sử là giá trị YES thì việc tạo Index lại tăng tốc độ thực hiện. Mặt khác do có nhiều loại Index với các u nhợc điểm riêng tuỳ thuộc vào từng đặc điểm dữ liệu do vậy cần chọn phơng pháp Index thích hợp nh Index thông thờng tốt khi câu lệnh có tính chọn lọc cao, Index Bitmap có tác dụng khi số hàng nhiều, giá trị lặp lại ít (tính chọn lọc thấp), Cluster thích hợp cho các bảng có liên kết đợc dùng thờng xuyên.
SELECT ... FROM NhânViên WHERE M NhânViên=11103;ã
I/O
Index MãNhânViên
Hash
Key Cluster Key
237 M NhânViênã Cột khác ... 1297 ... 1321 ... 1298 ... 238 ... 11028 ... 11021 ... 11103 ... M NhânViênã Các cột khác ... 12917 ... 13021 12981 ... 11028 ... 11021 ... 11103 ... 11103 - rowid I/O I/O I/O I/O Bảng NhânViên Cluster chứa bảng NhânViên
Truy nhập qua hàm băm và qua Index
5. Tối u bằng thay đổi câu lệnh SQL
Đây là phần trọng tâm của quá trình tối u câu lệnh SQL để cho các câu lệnh SQL mới tơng đơng câu lệnh SQL cũ về mặt kết quả nhng có thời gian chạy nhanh hơn nhiều. Mặc dù Oracle hỗ trợ cho việc tối u các câu lệnh SQL đa vào tuy nhiên trong một số trờng hợp ngời phát triển phần mềm phải tự chuyển câu lệnh thành câu lệnh có kết quả tơng đơng cho tối u hơn nh câu lệnh
thành: SELECT TênNhânViên, Lơng FROM NhânViên WHERE Lơng>2,000;
Trong phụ lục B sẽ giới thiệu về quá trình tối u bằng thay đổi câu lệnh trên view của phần mềm Tra cứu văn bản pháp qui. Thời gian thực hiện câu lệnh cha tối u là 41.43 giây, sau khi tối u thời gian thực hiện còn 2.36 giây (bằng 4.8 %).
Trong phụ lục C sẽ giới thiệu về quá trình tối u bằng thay đổi câu lệnh kết nối cũng của phần mềm Tra cứu văn bản pháp qui. Thời gian thực hiện câu lệnh cha tối u là 1.16 giây, sau khi tối u thời gian thực hiện xấp xỉ 0 giây.
Nh vậy thực tế là qua hai quá trình tối u thì khi tra cứu thông tin về Văn bản pháp qui do Văn phòng chính phủ và UBND các tỉnh ban hành bằng Web trên mạng thì thời gian đáp ứng từ 41.43 giây xuống xấp xỉ 1.2 giây. Thời gian đáp ứng nằm ở quá trình Dial up và hiển thị của trình duyệt Web.
Một số ví dụ khác về quá trình tối u sẽ đợc giới thiệu trong phần tối u hoá Hệ tính hoá đơn nớc và quản lý khách hàng của công ty cấp nớc Thành phố Hồ Chí Minh (WSC).
6. Thêm các chỉ thị thực hiện vào trong câu lệnh
Lý do để thêm các chỉ dẫn: Bất kì ngời thiết kế phần mềm nào cũng biết rõ về đặc điểm về dữ liệu hơn Oracle vì vậy trong một số trờng hợp cần chỉ dẫn cho Oracle thực hiện câu lệnh theo hớng mong muốn.
Ví dụ:
SELECT * FROM tab1 WHERE col1=’A’; SELECT * FROM tab1 WHERE col1=’B’;
Giả sử rằng cột col1 của bảng tab1 chứa các kí tự từ ‘A’ đến ‘Z’ với số lợng là 1000 dòng trong đó 75% số dòng chứa kí tự ‘A’ và mỗi kí tự còn lại chiếm 1% số dòng của bảng. Với câu lệnh thứ nhất dùng phơng pháp duyệt toàn bộ sẽ nhanh hơn sử dụng Index còn trong câu lệnh thứ hai thì sẽ dùng Index thì lại nhanh hơn duyệt toàn bộ. Nh vậy bằng việc sử dụng chỉ dẫn Oracle có thể thực hiện câu lệnh hiệu quả hơn (bộ tối u sẽ sử dụng Index cho cả hai câu lệnh).
Các chỉ dẫn có thể áp dụng cho các câu lệnh đơn SELECT, UPDATE, INSERT và viết theo cú pháp sau:
DELETE SELECT UPDATE /*+ chỉ dẫn chú thích */ hoặc
DELETE SELECT UPDATE
--+ chỉ dẫn
chú thích
Các chỉ dẫn phải đi ngay sau các từ khoá DELETE, UPDATE, INSERT.
Dấu cộng (+) là chỉ thị báo cho Oraclebiết rằng bắt đầu các chỉ dẫn thông dịch và trong các chỉ dẫn này có thể có chứa các chú thích. Có các kiểu chỉ dẫn thực hiện chọn luật tối u, chọn cách truy nhập, chọn thứ tự kết nối và chọn thao tác kết nối.
6.1. Chỉ dẫn chọn luật tối u
ALL_ROWS: Chỉ đẫn này báo cho Oraclebiết phải sử dụng luật tối u ớc lợng giá cho khối lệnh sao cho tổng số tài nguyên đợc sử dụng là tối thiểu (nghĩa là số khối lệnh đợc xử lý đồng thời là tối đa).
Ví dụ:
SELECT /*+ ALL_ROWS */ M NhânViên,TênNhânViên FROM NhânViên WHEREã
M NhânViên=7566;ã
FIRST_ROWS: Chỉ dẫn chọn luật tối u ớc lợng giá với thời gian đáp ứng là tối thiểu (và tối thiểu nguồn tài nguyên đợc sử dụng để trả lại hàng đầu tiên). Chỉ dẫn này sẽ ép Oracle chọn phơng thức truy nhập bằng Index thay cho duyệt toàn bộ (nếu có sẵn Index). Nếu không có sẵn Index thì Oracle sẽ sử dụng phơng thức truy nhật bằng Nested-loop thay cho Merge-sort. Chỉ dẫn này không có tác dụng khi câu lệnh sử dụng toán tử tập hợp (UNION, INTERSEC, MINUS, UNION ALL), mệnh đề GROUP BY, mệnh đề FOR UPDATE, hàm làm việc với nhóm hàng (MIN, MAX, SUM, COUNT) và toán tử DISTINCT.
CHOOSE: Chỉ dẫn này cho phép Oracle chọn luật tối u dựa trên thông tin trong từ điển dữ liệu, nếu có thông tin về các bảng thì luật tối u ớc lợng đợc áp dụng còn ngợc lại thì áp dụng luật tối u cơ bản.
RULE: áp dụng luật tối u cơ bản cho câu lệnh.
6.2. Chỉ dẫn về chọn phơng thức truy nhập
FULL: Sử dụng phơng thức duyệt toàn bộ với một bảng đặc biệt bằng chỉ dẫn FULL(<tên bảng hoặc bí danh>) và nên sử dụng bí danh (alias) cho tên bảng.
Ví dụ:
SELECT /*+ FULL(a) Không sử dụng Index cho bảng NhânViên có bí danh là a */ M NhânViên,ã
FROM NhânViên a
WHERE M NhânViên=7566;ã
ROWID: Sử dụng duyệt bảng bằng ROWID cho một bảng đặc biệt bằng chỉ dẫn
ROWID(<tên bảng hoặc bí danh>).
CLUSTER: Chọn phơng thức duyệt bằng Cluster cho một bảng bằng chỉ dẫn
CLUSTER(<tên bảng hoặc bí danh>) Ví dụ:
SELECT --+ CLUSTER NhânViên TênNhânViên, M Phòngã
WHERE M Phòng=10 AND NhânViên.M Phòng=Phòng.M Phòng;ã ã ã
HASH: Chọn phơng thức truy nhập băm (hash scan) cho một bảng bằng chỉ dẫn HASH(<tên bảng hoặc bí danh>).
INDEX: Chọn cách truy nhập bằng Index cho một bảng theo cú pháp sau
INDEX ( <tên bảng hoặc bí danh> --+
Index
)
Nếu danh sách Index có nhiều giá trị thì Oracle sẽ ớc lợng giá của phơng thức duyệt ứng với mỗi Index và chọn ra phơng thức nào có giá nhỏ nhất. Nếu không Index đợc chỉ ra trong danh sách thì Oracle sẽ tiến hành ớc lợng giá thông qua các Index có sẵn trong CSDL đang truy nhập.
Ví dụ:
SELECT /*+ INDEX(NhânViên giớitính_index) sử dụng Index trên cột giới tính của bảng NhânViên khi mà có ít nữ : GiớiTính=0 */
TênNhânViên, Lơng WHERE GiớiTính=0;
INDEX_ASC: Chỉ dẫn chọn phơng thức truy nhập qua Index và nếu Index đó là
duyệt có giới hạn (Index Range Scan) thì sẽ theo chiều tăng dần của giá trị đợc Index.
INDEX_ASC ( <tên bảng hoặc bí danh> --+
Index
)
INDEX_DESC: Chỉ dẫn chọn phơng thức truy nhập qua Index và nếu Index đó là
duyệt có giới hạn (Index Range Scan) thì sẽ theo chiều giảm dần của giá trị đợc Index.
INDEX_DESC ( <tên bảng hoặc bí danh> --+
Index
)
AND_EQUAL: Chọn phơng thức truy nhập bằng duyệt trên nhiều Index đơn. Tối
thiểu phải có hai Index đơn và tối đa là năm Index đơn. AND_EQUAL ( <tên bảng hoặc bí danh> Index Index
Index
)
Index Index
USE_CONCAT: Chỉ dẫn này buộc điều kiện OR trong mệnh đề WHERE chuyển thành query sử dụng toán tử tập hợp UNION ALL. Thông thờng việc chuyển này chỉ đ- ợc thực hiện khi giá của việc chuyển là nhỏ hơn với giá của câu lệnh ban đầu.
6.3. Chỉ dẫn về thứ tự kết nối trong câu lệnh sử dụng kết nối
ORDERED: Chỉ dẫn thứ tự kết nối tuân theo thứ tự xuất hiện tên các bảng trong mệnh đề FROM.
Ví dụ:
SELECT /*+ ORDERED */ tab1.col1, tab2.col2, tab3.col3 FROM tab1, tab2, tab3 WHERE tab1.col1=tab2.col1 AND tab2.col1=tab3.col1
Các ví dụ đầy đủ hơn sẽ đợc giới thiệu trong phụ lục D. • Chỉ dẫn cho quá trình chọn thao tác kết nối
USE_NL: Chỉ dẫn chọn thao tác kết nối Nested-Loop với bảng nội (inner table) đợc