0

Apache Derby Bài 45: Phân tích nhật ký hệ thống (derby.log) và khắc phục sự cố

Khi bạn gửi một câu lệnh SQL phức tạp chứa nhiều phép JOIN, WHERE, và GROUP BY để thống kê đơn hàng hay quản lý kho vận (logistics), Apache Derby không thực thi ngay lập tức. Engine sẽ chuyển câu lệnh này cho một bộ phận cực kỳ quan trọng gọi là Optimizer (Trình tối ưu hóa).

Optimizer hoạt động như một hệ thống định tuyến thông minh: Nó tính toán hàng tá "kịch bản" (đường đi) khác nhau để lấy dữ liệu, ước tính chi phí I/O ổ cứng cho từng kịch bản, và chọn ra con đường ngắn nhất. Con đường được chọn đó chính là Kế hoạch thực thi (Execution Plan).

image.png

1. Thu thập dữ liệu thống kê (Update Statistics)

Để Optimizer chọn đúng Kế hoạch thực thi, nó cần dữ liệu thống kê chính xác về bảng (số lượng dòng, độ phân tán dữ liệu của cột). Nếu bảng don_hang vừa được chèn thêm 1 triệu dòng mới nhưng Optimizer vẫn nghĩ bảng chỉ có 100 dòng, nó sẽ chọn Table Scan (Quét toàn bảng) thay vì dùng Index, dẫn đến hiệu năng tụt dốc.

Trong Derby, bạn cần chủ động cập nhật thống kê định kỳ bằng thủ tục hệ thống:

SQL

-- Cập nhật thống kê cho tất cả các Index trên bảng don_hang
CALL SYSCS_UTIL.SYSCS_UPDATE_STATISTICS('APP', 'DON_HANG', null);

2. Cách bật chức năng Runtime Statistics

Không giống như MySQL hay PostgreSQL có từ khóa EXPLAIN đặt trước câu truy vấn, Apache Derby sử dụng cơ chế Runtime Statistics. Bạn phải bật cờ theo dõi, chạy thử câu truy vấn, rồi gọi hàm trích xuất kết quả.

Quy trình 3 bước phân tích hiệu năng:

Bước 1: Bật bộ thu thập thống kê trong phiên làm việc hiện tại (Session).

SQL

CALL SYSCS_UTIL.SYSCS_SET_RUNTIMESTATISTICS(1);

Bước 2: Chạy câu truy vấn bạn muốn kiểm tra (ví dụ lấy danh sách đơn hàng đang vận chuyển).

SQL

SELECT ma_don, tong_tien FROM don_hang WHERE trang_thai = 'DANG_GIAO';

Bước 3: Trích xuất và đọc Kế hoạch thực thi vừa được sinh ra.

SQL

VALUES SYSCS_UTIL.SYSCS_GET_RUNTIMESTATISTICS();

3. Cách đọc hiểu Kế hoạch thực thi

Khi chạy hàm ở Bước 3, Derby sẽ trả về một chuỗi văn bản rất dài mô tả cấu trúc cây thực thi (Tree Plan). Các nút (node) quan trọng nhất bạn cần tìm kiếm bao gồm:

Table Scan (Quét toàn bảng)

Nếu bạn thấy dòng chữ Table Scan ResultSet, điều này có nghĩa là Derby đã phải đọc từ dòng đầu tiên đến dòng cuối cùng của bảng vật lý trên ổ đĩa.

  • Đánh giá: Rất chậm nếu bảng có hàng triệu dòng.

  • Khắc phục: Cần tạo Index (Bài 27) cho các cột nằm trong mệnh đề WHERE.

Index Scan (Quét chỉ mục B-Tree)

Nếu bạn thấy Index Scan ResultSet, chúc mừng bạn! Optimizer đã dùng cây nhị phân B-tree để nhảy thẳng đến các dòng thỏa mãn điều kiện.

  • Đánh giá: Tốc độ cực nhanh (O(log⁡n)O(\log n)).

Các thuật toán JOIN

Khi bạn kết nối 2 bảng (ví dụ don_hang và khach_hang), Optimizer sẽ chọn 1 trong 2 thuật toán vật lý:

  1. Nested Loop Join: Duyệt từng dòng của bảng A, rồi tìm các dòng tương ứng trong bảng B. Rất hiệu quả nếu bảng B đã được đánh Index trên cột khóa ngoại.

  2. Hash Join: Nạp toàn bộ dữ liệu cần thiết của bảng nhỏ hơn vào bộ nhớ RAM (dưới dạng Hash Table), sau đó quét bảng lớn để đối chiếu. Rất nhanh khi xử lý dữ liệu cực lớn, nhưng tiêu tốn nhiều RAM.

4. Tinh chỉnh hiệu năng (Tuning) thực tế

Giả sử Kế hoạch thực thi trả về Table Scan dù bạn đã tạo Index. Bạn cần ép Optimizer phải sử dụng Index đó. Derby hỗ trợ cú pháp Optimizer Overrides (Bắt ép tối ưu) ngay trong câu lệnh SQL thông qua từ khóa -- DERBY-PROPERTIES.

SQL

-- Ép Derby bắt buộc phải dùng Index có tên idx_don_hang_trang_thai
SELECT ma_don, tong_tien 
FROM don_hang 
-- DERBY-PROPERTIES index=idx_don_hang_trang_thai
WHERE trang_thai = 'DANG_GIAO';

(Lưu ý: Chỉ dùng tính năng bắt ép này khi bạn thực sự chắc chắn Index Scan sẽ nhanh hơn Table Scan, vì đôi khi Optimizer cố tình bỏ qua Index nếu điều kiện WHERE chiếm tới 80% số dòng của bảng).

Dữ liệu càng lớn, CSDL càng có xu hướng sinh ra nhiều "khoảng trống" (phân mảnh) trên ổ cứng sau hàng loạt thao tác Xóa/Sửa. Bài tiếp theo sẽ hướng dẫn cách dọn dẹp và thu hồi dung lượng: Apache Derby Bài 47: Khắc phục phân mảnh (Fragmentation) và nén dữ liệu.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí