Lập trình Go 22/09/2026 10 phút

Tinh chỉnh connection pool của database/sql trong Go: ba nút quyết định thông lượng

sql.DB không phải một kết nối — nó là một pool. Hiểu sai ba nút MaxOpenConns, MaxIdleConns, ConnMaxLifetime khiến app hoặc nghẽn cổ chai hoặc giết chết DB. Đo thật trong Go: cùng 1000 truy vấn, throughput đi từ 174 lên 8497 truy vấn mỗi giây khi chỉnh pool, và WaitCount về 0 khi đủ kết nối.

Lập trình Go 22/09/2026 10 phút

sqlc trong Go: viết SQL, sinh code Go an toàn kiểu — bắt lỗi lúc biên dịch

ORM giấu SQL và dùng reflection; database/sql viết tay linh hoạt nhưng Scan thủ công dễ sai và lỗi tên cột chỉ lộ lúc chạy. sqlc lật ngược: bạn viết SQL thật, nó sinh code Go an toàn kiểu và kiểm SQL so với schema ngay lúc sinh. Đo thật: sqlc bắt cột không tồn tại trước cả khi biên dịch Go.

Lập trình Go 22/09/2026 10 phút

Prepared statement caching trong Go: chuẩn bị một lần, chạy nhiều lần

Một câu lệnh có tham số đi qua hai pha ở DB: PREPARE (phân tích + lập kế hoạch, đắt) và EXECUTE (rẻ). Chạy cùng câu lệnh N lần mà prepare lại mỗi lần là lãng phí. Đo thật trong Go: 500 truy vấn với prepare mỗi lần mất 1.98s (500 prepare), prepare một lần rồi tái dùng chỉ 673ms (1 prepare) — nhanh 2.9 lần.

Lập trình Go 22/09/2026 10 phút

Batch insert trong Go: vì sao chèn từng dòng chậm gấp trăm lần

Chèn N dòng bằng N lệnh Exec là N vòng đi-về mạng, mỗi vòng trả giá độ trễ cố định. Nút thắt là SỐ round-trip, không phải tốc độ chèn một dòng. Đo thật trong Go: chèn 2000 dòng từng cái mất 2.6s (2000 round-trip); multi-row INSERT gộp lô 200 chỉ 14ms (10 round-trip) — nhanh 193 lần.

Lập trình 22/09/2026 6 phút

Đọc EXPLAIN ANALYZE: query plan là ống nghe của bác sĩ database, và cách nghe cho đúng

Query chậm mà không biết vì sao? EXPLAIN ANALYZE cho biết database THỰC SỰ làm gì với query của bạn. Bài này đo thật trên bảng 1 triệu dòng trong PostgreSQL: cùng một query, chưa index chạy Seq Scan mất 10.764ms (quét cả bảng, đọc 7353 block); thêm index thành Bitmap Index Scan còn 0.116ms (14 block) — nhanh 93 lần. Kèm cách đọc từng con số: cost không phải ms, actual time mới thật, và rows dự đoán vs thật lộ khi planner đoán sai.

Lập trình 22/09/2026 6 phút

Index B-tree: vì sao tạo index rồi vẫn Seq Scan — bẫy non-sargable và cách viết query cho đúng

Bạn tạo index nhưng query vẫn chậm và EXPLAIN vẫn báo Seq Scan? Vì predicate không sargable — chỉ cần bọc cột trong một hàm là index nằm im vô dụng. Bài này đo thật trên bảng 1 triệu dòng: WHERE email=x dùng index (0.045ms), nhưng lower(email)=x quét cả bảng (54.857ms); age+1=31 chậm 12ms còn age=30 chỉ 1ms; và một bất ngờ — LIKE 'x%' với index thường vẫn Seq Scan, phải dùng text_pattern_ops.