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

'CTE luôn chậm hơn subquery' — lời khuyên đúng năm 2018, sai 720 lần trên PostgreSQL đời mới

Mang niềm tin cũ 'CTE là hàng rào tối ưu, luôn chậm hơn subquery', tôi viết CTE thường rồi ngồi đợi nó chậm. Đo ra nhanh y hệt subquery — 0,134ms, index scan — vì từ PG12 CTE được inline. Chỉ khi ép AS MATERIALIZED thì hàng rào cũ mới trở lại: 95ms, chậm 720 lần cho cùng logic. Vì sao một luật hiệu năng hết hạn theo phiên bản.

Giải thuật 03/09/2026 8 phút

sem_wait không phải lúc nào cũng là syscall — cùng một lời gọi chênh nhau 4.800 lần

Tưởng mỗi sem_wait là một syscall đắt nên phải né semaphore ở đường nóng? Tôi đo: khi bộ đếm còn dương, sem_wait chỉ là một phép atomic ~1,8 ns, chẳng vào nhân; chỉ khi phải ngủ mới tốn ~8.695 ns (futex + chuyển ngữ cảnh) — chênh gần 4.800 lần. Cái đắt là phải ngủ, không phải cái tên hàm.

Giải thuật 03/09/2026 8 phút

'Random Access Memory' mà truy cập ngẫu nhiên chậm 423 lần: sức mạnh prefetch

Tưởng truy cập RAM nào cũng như nhau (Random Access Memory), và prefetch chỉ giúp đọc stride 1? Tôi đo thử: duyệt mảng tuần tự 0,28ns/phần tử vs ngẫu nhiên 107ns — chênh 423 lần, vì prefetcher phần cứng chỉ đoán được mẫu ĐỀU; cái giết nó là tính không đoán được, không phải khoảng cách.

Giải thuật 03/09/2026 8 phút

256 nhánh if-else chậm hơn bảng nhảy 121 lần — nhưng 4 nhánh thì không

Nhiều if-else cũng nhanh như switch, compiler lo hết? Tôi đo thử: chuỗi quét tuyến tính là O(N) — 256 nhánh mất 35,57ns còn bảng nhảy 0,24ns, chậm 121 lần. Nhưng ở 2-4 nhánh, if-else viết tay ngang bảng, và phân bố lệch làm branch prediction gần miễn phí. Đây là một điểm giao, không phải câu trả lời một chiều.

Giải thuật 03/09/2026 5 phút

Khi 'perf' báo Operation not permitted mà vẫn đo được branch-miss

Người ta bảo muốn biết cache-miss hay branch-miss thật thì phải có perf và bộ đếm phần cứng. Máy tôi đo thì perf còn chẳng chạy — VM khóa luôn PMU. Vậy mà chỉ với một cái đồng hồ và một thí nghiệm đổi đúng một biến, branch-miss vẫn hiện ra rõ mồn một, chậm gần 7 lần.