Q

Quản trị viên

Là một lập trình viên yêu công nghệ, thích viết blog để chia sẻ kiến thức, kinh nghiệm lập trình và những điều thú vị trong thế giới tech.

2300 bài viết · Website
Cơ sở dữ liệu 03/09/2026 9 phút

Prepared statement tưởng luôn nhanh — hóa ra có lúc quét cả bảng, chậm gấp trăm lần

Tưởng prepared statement luôn nhanh hơn nhiều — đo query nhẹ chỉ nhanh 13%. Nguy hơn: sau 5 lần chạy PostgreSQL có thể đổi sang generic plan, và trên cột lệch nó quét cả bảng 13ms thay vì index scan 0,13ms — nhanh ở khâu parse nhưng chậm gấp trăm ở khâu thực thi. Vẫn phải luôn tham số hóa, vì lý do quan trọng hơn tốc độ.

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

Bảng đứng yên 14 MB, nhưng index âm thầm phình gấp đôi — và VACUUM không bao giờ cứu

VACUUM bảng sau mỗi vòng, thấy bảng đứng yên 14 MB nên tưởng mọi thứ gọn sạch. Nhưng index kẹt ở 8792 kB, mật độ lá chỉ 45% — phình gấp đôi, và VACUUM không bao giờ sửa nổi. Chỉ REINDEX mới nén lại cây. Vì sao phải đo cả index chứ không chỉ bảng, và HOT update giảm phình ngay từ đầu.

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 8 phút

Nạp 100.000 dòng: INSERT mất 8,5 giây, COPY chỉ 62ms — cùng dữ liệu, nhanh 137 lần

Nạp 100.000 dòng bằng INSERT từng dòng mất 8,5 giây, suýt kết luận 'ghi vào CSDL vốn chậm'. Nhưng COPY nạp đúng 100.000 dòng đó chỉ 62ms — nhanh 137 lần, cùng dữ liệu, cùng độ bền. Cái chậm không phải việc ghi mà là mỗi dòng một commit và mỗi câu một lần parse. Đo bốn cách nạp, và tiền thời gian thật đi đâu.

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ó.