Cơ sở dữ liệu 03/09/2026 9 phút

Cột text 5KB tưởng làm chậm cả bảng — hóa ra vô hình, trừ khi bạn SELECT *

Tôi tưởng một cột text 5KB làm mọi truy vấn trên bảng chậm. Đo: SUM(tag) chỉ 1,5ms vì giá trị lớn nằm ngoài bảng chính, ở TOAST; chỉ khi truy vấn chạm cột đó mới chậm (420ms, ~280 lần). Và nén quyết định tất cả: cùng 5KB×50k hàng, text lặp còn 6,8 MB, dữ liệu ngẫu nhiên phình thành 300 MB.

Cơ sở dữ liệu 03/09/2026 9 phút

Truy vấn chậm nhất không phải thủ phạm: cái tra index 0,0075ms lại ngốn gấp 16 lần

Theo phản xạ, tôi lao vào tối ưu truy vấn chậm nhất (23ms một lần). Nhưng nó là báo cáo chạy 2 lần — tổng chỉ 47ms. Trong khi một truy vấn tra index chỉ 0,0075ms mỗi lần, gọi 100000 lần, ngốn 754ms — gấp 16 lần. pg_stat_statements xếp theo TỔNG thời gian mới lộ thủ phạm thật: chi phí = mỗi lần × tần suất.

Cơ sở dữ liệu 03/09/2026 9 phút

Phân vùng bảng: prune còn 1/12 số trang, DROP vùng cũ nhanh 34 lần — nhưng chỉ khi hỏi đúng khóa

Phân vùng theo thời gian: truy vấn lọc theo khóa phân vùng chỉ quét 1 vùng (541 trang) thay vì cả bảng (6487 trang), và DROP một vùng cũ mất 1,5ms so với DELETE 51ms. Nhưng truy vấn không chứa khóa phân vùng phải quét cả 12 vùng — chẳng lợi gì. Vì sao chọn đúng khóa phân vùng quyết định tất cả.

Cơ sở dữ liệu 03/09/2026 9 phút

synchronous_commit=off cho throughput gấp đôi — và tôi suýt quên nó đang bí mật vứt dữ liệu

Bật synchronous_commit=off thấy tps gấp đôi, suýt kết luận 'cứ tắt cho nhanh'. Nhưng đó là đánh đổi độ bền. Đo lại: 8 luồng sync=on nhờ group commit đạt 37689 tps — còn cao hơn sync=off một luồng, mà vẫn bền nguyên. Mỗi commit là một fsync, và fsync mới là nút cổ chai thật; cách gỡ nó không phải bỏ nó.

Cơ sở dữ liệu 03/09/2026 9 phút

'read=12760' trong EXPLAIN không có nghĩa xuống đĩa: bí mật của tầng cache thứ hai

Thấy EXPLAIN ghi read=12760, tôi đinh ninh 12760 trang đó lôi từ đĩa lên nên hẳn phải chậm. Nhưng thời gian 17ms ổn định y hệt suốt ba lần quét — chúng do OS page cache phục vụ từ RAM, không phải đĩa. 'read' chỉ nghĩa là 'không có trong shared_buffers', không phải 'từ đĩa'. Đo tận mắt hai tầng cache, và vì sao shared_buffers to hết cỡ lại chậm hơn.

Cơ sở dữ liệu 03/09/2026 9 phút

COMMIT xong nhưng data chưa ra đĩa: 127MB còn nằm trong RAM, và cú checkpoint dồn tất cả xuống một lúc

INSERT rồi COMMIT xong, tôi đinh ninh dữ liệu đã nằm an toàn trong file trên đĩa. Đo pg_buffercache mới ngã ngửa: 16320 trang vẫn bẩn trong shared_buffers, chưa hề chạm file data. Cái làm COMMIT bền là WAL fsync; trang data xuống đĩa muộn hơn, cả lô ở checkpoint — một cú bùng I/O 79ms. Vì sao max_wal_size nhỏ làm CSDL giật, và cách làm phẳng.