Phân mảnh (Fragmentation) trong cơ sở dữ liệu xảy ra khi dữ liệu trong bảng hoặc chỉ mục không được lưu trữ liên tục trên đĩa. Điều này có thể làm giảm hiệu suất truy vấn vì cơ sở dữ liệu phải đọc dữ liệu từ nhiều vị trí khác nhau, thay vì đọc liên tục từ một khối duy nhất.
I. Nguyên nhân gây phân mảnh bảng
1. Cập nhật hoặc xóa dữ liệu:
• Khi bản ghi trong bảng bị xóa hoặc cập nhật, không gian của bản ghi cũ có thể bị để trống. Các bản ghi mới không nhất thiết được chèn vào cùng vị trí, dẫn đến dữ liệu phân tán.
2. Thêm dữ liệu không đồng nhất:
• Nếu cơ sở dữ liệu cần thêm dữ liệu mới nhưng không còn đủ không gian liền kề, nó sẽ lưu dữ liệu vào một vị trí trống khác.
3. Tăng kích thước bản ghi:
• Khi một bản ghi được cập nhật với dữ liệu lớn hơn kích thước ban đầu, nó có thể không vừa với vị trí cũ. Hệ thống sẽ phải lưu phần dữ liệu thừa vào vị trí khác.
4. Giảm dung lượng lưu trữ ban đầu:
• Cấu hình ban đầu không đủ để chứa tất cả dữ liệu tăng trưởng, buộc hệ thống phải mở rộng phân bổ dữ liệu sang các vị trí khác.
II. Tác động của bảng bị phân mảnh
1. Hiệu suất giảm:
• Truy vấn dữ liệu chậm hơn vì hệ thống phải đọc từ nhiều vị trí trên đĩa thay vì từ một khối liên tục.
• Điều này đặc biệt ảnh hưởng đến các truy vấn toàn bảng (full table scans) hoặc truy cập dữ liệu tuần tự.
2. Tăng sử dụng tài nguyên:
• Phân mảnh làm tăng số lần đọc/ghi I/O, tiêu tốn thêm tài nguyên CPU và bộ nhớ.
3. Lãng phí không gian lưu trữ:
• Các khoảng trống không được sử dụng giữa các bản ghi có thể gây lãng phí dung lượng đĩa.
III. Cách phát hiện phân mảnh trong cơ sở dữ liệu
1. Oracle:
Sử dụng các truy vấn sau để kiểm tra:
SELECT table_name, pct_free, pct_used FROM user_tables;
• PCT_FREE: Tỷ lệ phần trăm không gian trống còn lại trong các khối của bảng.
• PCT_USED: Tỷ lệ phần trăm không gian được sử dụng.
2. SQL Server:
Sử dụng lệnh sau để kiểm tra mức độ phân mảnh:
SELECT index_id, avg_fragmentation_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(), OBJECT_ID('TableName'), NULL, NULL, 'DETAILED');
3. PostgreSQL:
Chạy lệnh VACUUM VERBOSE để kiểm tra các khối dữ liệu không sử dụng.
IV. Cách khắc phục phân mảnh
1. Rebuild Index (Tái tạo chỉ mục):
• Trong nhiều hệ quản trị cơ sở dữ liệu, việc tái tạo chỉ mục sẽ sắp xếp lại dữ liệu và giảm phân mảnh.
• Ví dụ trong SQL Server:
ALTER INDEX index_name ON table_name REBUILD;
2. Shrink Table (Thu nhỏ bảng):
• Giải phóng không gian trống không cần thiết.
• Ví dụ trong Oracle:
ALTER TABLE table_name SHRINK SPACE;
3. Export/Import Table (Xuất nhập bảng):
• Xuất dữ liệu từ bảng, xóa bảng cũ và nhập lại dữ liệu để tối ưu hóa việc lưu trữ.
4. Cluster Table (Tái tổ chức bảng):
• Một số cơ sở dữ liệu (như PostgreSQL) hỗ trợ lệnh CLUSTER để tổ chức lại dữ liệu trong bảng.
• Ví dụ:
CLUSTER table_name USING index_name;
V. Cách phòng ngừa phân mảnh
1. Thiết kế bảng hợp lý:
• Sử dụng kích thước khối (block size) phù hợp và cấu hình PCT_FREE để đảm bảo không gian trống cho các bản ghi được cập nhật.
2. Tối ưu hóa index:
• Thường xuyên kiểm tra và tái tạo chỉ mục để giảm phân mảnh.
3. VACUUM (PostgreSQL) hoặc DBMS_STATS (Oracle):
• Dọn dẹp định kỳ để giải phóng không gian và sắp xếp lại dữ liệu.
4. Quản lý dữ liệu:
• Xóa dữ liệu không cần thiết hoặc thiết lập lưu trữ dữ liệu (archiving) thay vì để quá tải bảng chính.