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

Một hàng UPDATE 10.000 lần phình bảng lên 360KB — vì PostgreSQL không hề sửa tại chỗ

UPDATE một cột không sửa tại chỗ: ctid đổi từ (0,1) sang (0,2), bản cũ thành dead tuple. Tôi tưởng UPDATE ghi đè giá trị, bảng giữ nguyên; đo ra một hàng UPDATE 10.000 lần làm bảng phình từ 8KB lên 360KB với 10.000 xác chết. Đây là MVCC — mỗi thay đổi để lại một phiên bản cũ, và vì sao đọc-ghi đồng thời mượt.

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

Quên một chữ BEGIN, 500 đồng bốc hơi khỏi hệ thống — bài học nguyên tử của giao dịch

Chuyển 500 mà lỗi giữa hai UPDATE: không giao dịch làm tổng tụt từ 2000 còn 1500 (mất 500 trong không khí); bọc BEGIN...COMMIT thì ROLLBACK giữ nguyên 2000. Mặc định là autocommit — mỗi lệnh tự commit, nên hai lệnh liên tiếp KHÔNG tự thành một đơn vị. Tính nguyên tử đo bằng một bất biến: tổng tiền.

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

Đọc cùng một hàng hai lần trong một giao dịch mà ra hai số khác nhau — chuyện gì vậy?

Đọc cùng một hàng hai lần trong một giao dịch: ở mặc định READ COMMITTED được 100 rồi 200; REPEATABLE READ giữ 100; SERIALIZABLE có thể hủy giao dịch bắt bạn retry. Tôi tưởng 'đọc lại thì y nguyên chứ' — hóa ra mặc định KHÔNG phải mức chặt nhất, và mức cô lập là biến ẩn quyết định bạn thấy gì.

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

Tắt fsync chỉ nhanh gấp 2 lần? Con số đó đúng — và cũng đánh lừa tôi hoàn toàn

Tắt fsync (synchronous_commit=off) chỉ nhanh gấp 2 lần trong đo của tôi — vì đĩa container là đĩa ảo nhanh; trên ổ cứng thật nó nhanh gấp hàng chục lần. WAL là thứ làm COMMIT bền, fsync là cái giá, và cái giá đó phụ thuộc hoàn toàn vào tốc độ đĩa. Gộp 3000 hàng vào 1 giao dịch = 1 fsync, nhanh gấp trăm lần.

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

int hay bigint hay text — đo ra cùng 35 MB, và vì sao kết luận đó gần như sai hoàn toàn

Đo dung lượng bằng bảng một cột: int, bigint, numeric, text đều ra 35 MB y hệt — tôi suýt kết luận kiểu chẳng ảnh hưởng. Header hàng 23 byte đã trùm mất khác biệt. Cho cột thành phần lớn của hàng thì bigint 89MB so int 57MB, numeric chậm 2,7 lần, và text so số sai ('10' < '9'). Chọn kiểu là chuyện dung lượng, tốc độ, và tính đúng.

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

Hash join 78ms hay 223ms cho cùng một câu? Con số 'Batches' trong EXPLAIN nói tất cả

Join hai bảng lớn: hash join 78ms (bảng băm vừa RAM, Batches=1), nhanh gần 3 lần nested loop. Nhưng work_mem nhỏ làm bảng băm tràn 16 batch ra đĩa và chậm hẳn. Tôi suýt kết luận 'hash join nhanh' vô điều kiện — cho tới khi hạ work_mem và thấy Batches nhảy lên 16. Đọc Batches, không chỉ thời gian tổng.