DuckDB nhanh vì nó bỏ qua cái khúc ai cũng quên
Mổ xẻ bên trong DuckDB: vì sao một engine SQL chạy ngay trong tiến trình, bỏ qua mạng, lại nhanh hơn cả cụm máy chủ triệu đô, và dân HN nghĩ gì.
Lần đầu DuckDB làm tôi quê là khi tôi có file Parquet 6 GB và một cái deadline. Quy trình “đàng hoàng” là upload file lên đâu đó, ngồi chờ cái warehouse thức dậy, rồi gõ một câu CREATE TABLE mà tôi biết một tiếng sau sẽ xoá. Thay vào đó tôi gõ SELECT * FROM 'orders.parquet' ngay trên laptop. Kết quả về trước khi tay tôi kịp với ly cà phê.
Tôi tưởng có mánh gì đó. Không. Cái nhanh nằm ở chỗ nó không làm gì cả.
Kyle Cheung bên Greybeam viết loạt bài ba phần mổ xẻ ruột gan DuckDB, và Phần 1 chính là cái lên top HN. Nó đi theo đúng một câu query, từ lúc bước vào engine đến lúc sẵn sàng chạy. Cái hay là suốt bài tác giả cứ lặp lại đúng một câu hỏi cộc lốc ở mỗi chặng: chỗ này nhanh nhờ đâu?
Câu chuyện gói trong một câu
DuckDB là một cơ sở dữ liệu SQL phân tích chạy ngay trong tiến trình của bạn - một file binary chưa tới 20 MB, không server, không port, không daemon - bạn nạp nó như nạp một thư viện rồi chĩa thẳng vào đống file Parquet, CSV, JSON như thể chúng đã là database sẵn.
Hình dạng nó chỉ có vậy. pip install duckdb. Rồi viết SQL trên file. Không có connection string nào hết.
Cái khúc ai cũng quên
So sánh độ trễ: Chạy in-process trực tiếp trong bộ nhớ vs. đóng gói qua giao thức mạng:
Lựa chọn thiết kế mà cả bài xoay quanh lại nằm ngoài engine query. Nó nằm ở chỗ: mạng.
Đa số database phân tích là server. Snowflake, BigQuery, Redshift, Postgres. Bạn mở kết nối, gửi SQL qua socket, kết quả chạy ngược về qua dây. Trên đường đi, mỗi giá trị trong kết quả bị serialize thành chuỗi byte, đẩy qua TCP, rồi parse lại ở đầu kia.
Năm 2017, Mark Raasveldt và Hannes Mühleisen - đúng hai người sau này làm ra DuckDB - đăng một bài báo với cái tựa hay nhất ngành database: Don’t Hold My Data Hostage (đừng bắt cóc dữ liệu của tôi). Họ đo xem chuyện gì thực sự xảy ra khi bạn kéo một tập kết quả ra khỏi warehouse. Bản thân cái giao thức client, ODBC với JDBC, thường là khúc chậm nhất trong cả câu query. Có khi nó tốn thời gian hơn cả việc tính ra đáp án.
Hai lý do. Đường gigabit chỉ tầm 125 MB/s, nên kết quả lớn có khi truyền lâu hơn tính. Và ODBC trả dữ liệu từng giá trị một - với kết quả 100 triệu dòng thì đó là hàng trăm triệu lần gọi hàm, mỗi lần tự copy bộ nhớ, tự kiểm tra kiểu.
DuckDB né cả hai bằng cách sống chung tiến trình với code của bạn. Không có gì để serialize hết. Khi bạn query một dataframe pandas, cái “replacement scan” cho phép DuckDB đọc thẳng buffer mà tiến trình Python của bạn đang giữ. NumPy bảo “đây, một triệu số int64”, DuckDB đọc luôn đúng cái buffer đó. Zero copy, không sao chép.
Từ SQL ra kế hoạch, trong khoảng một mili giây
Khi SQL đã vào trong engine, nó đi qua đúng các bước quen thuộc: parse, bind, plan, optimize. DuckDB fork luôn cái parser của Postgres, nên cú pháp của nó thấy thân quen lạ.
Khúc optimizer mới là chỗ làm tôi mở terminal ra gõ thật. DuckDB phơi luôn optimizer ra thành một danh sách các bước nhỏ có tên, bạn xem được và tắt được từng cái:
SELECT * FROM duckdb_optimizers();
-- 33 dòng: filter_pushdown, join_order, row_group_pruner,
-- late_materialization, common_subexpressions, ...
Bạn chạy SET disabled_optimizers = 'filter_pullup, join_order' rồi nhìn xem thiếu một bước thì nó hư ra sao. Cả pha optimize thường xong trong khoảng một mili giây.
Nặng nhất là chọn thứ tự join. Một câu join sáu bảng có 30.240 hình dạng cây khác nhau, và khoảng cách giữa cách tốt nhất với cách tệ nhất chênh nhau cả mấy bậc độ lớn. DuckDB mô hình hoá query thành một đồ thị, rồi dùng quy hoạch động (DPhyp, DPccp) để khỏi tính lại những thứ tự nó đã giải xong. Đúng cái mánh làm Fibonacci nhanh, đem áp vào chuyện bảng nào gặp bảng nào trước.
Nửa còn lại: đừng bao giờ đọc cái mình không cần
File gốc của DuckDB là một file .duckdb duy nhất, học từ SQLite. Bên trong, dữ liệu xếp theo cột, chia thành block 256 KB, mỗi block mang một checksum để một bit lật trên ổ SSD laptop biến thành lỗi báo ra, chứ không thành đáp án sai.
Chi tiết quyết định tốc độ là zone map. Mỗi row group (tối đa 122.880 dòng) lưu min và max của từng cột, kèm số lượng null. Khi bạn chạy WHERE event_date > '2026-01-01', DuckDB nhìn max của từng row group trước, thấy không khớp nổi thì bỏ qua nguyên cụm. Nó không đọc dữ liệu luôn.
Mánh này không có gì lạ. Đúng cái ý tưởng mà mấy warehouse đắt tiền xài, chỉ khác cái tên đẹp hơn:
| Engine | Họ gọi là gì |
|---|---|
| DuckDB | zone map |
| Snowflake | micro-partition pruning |
| BigQuery | block pruning |
| ClickHouse | minmax data-skipping index |
Mà khi query Parquet trực tiếp, DuckDB còn chẳng cần tới định dạng riêng. Parquet vốn đã lưu min/max theo từng row group, nên DuckDB đọc footer, quyết xem row group nào thoả điều kiện, rồi chỉ lấy đúng mấy cột cần. Với file ở xa, nó gửi một request HTTP lấy mỗi cái footer, rồi range-request đúng số byte cần đọc. Một câu WHERE viết khéo trở thành cách để tải về ít file hơn.
Dân HN đang cãi nhau chuyện gì
Cái thread phần lớn là khen, mà bản thân chuyện đó cũng là một dấu hiệu - DuckDB hiếm khi dính cái nghi ngờ kiểu HN. steve_adams_86 chốt đúng cái đồng thuận: anh xài vì nó dễ, ở lại vì hoá ra nó “giỏi tới mức vô lý”, và “tới giờ vẫn làm tôi nể đều đều”. anitil chỉ ra chỗ đặc biệt: đa số dự án giỏi việc nhỏ hoặc giỏi việc lớn. DuckDB giỏi cả hai.
0xferruccio đưa ra cái use case đậm chất 2026 nhất thread: bơm log mọi phiên Claude Code của từng kỹ sư từ S3 vào DuckDB để tìm chỗ developer experience đang hổng. Đúng cái việc keo dán âm thầm.
Nhưng comment sắc nhất lại là tiếng nói ngược. willtemperley nhắc rằng “chỉ là thư viện” có một cạnh sắc: nếu bạn không link động được - ví dụ trong môi trường App Store - thì DuckDB hơi khó xài, vì link tĩnh mấy extension của nó cực kỳ chật vật. “DuckDB tuyệt thật, nhưng nó giống hộp đen hơn là thư viện.” Trong thế giới đó anh chọn Arrow C++, vì nó build portable hơn. Cái thiết kế chạy-trong-tiến-trình làm DuckDB nhanh, cũng chính là cái bắt bạn nhúng nó theo điều kiện của nó, chứ không theo điều kiện của bạn.
Có nên đọc bài gốc không?
| Nên đọc nếu… | Khỏi đọc nếu… |
|---|---|
Bạn xài DuckDB và muốn biết vì sao câu WHERE lại bỏ qua file đó |
Bạn chỉ cần công thức nấu ăn, không cần ruột gan |
| Bạn muốn một mô hình rõ ràng parse → bind → optimize → plan | Bạn đã thuộc lòng columnar storage với zonemap |
| Bạn thích nhìn một câu query bị bám đuôi từ đầu tới cuối | Bạn mong đọc Phần 2 - khúc thực thi nằm ở bài sau |
Đây là Phần 1 trong ba, và nó dừng ngay trước khúc thực thi: xử lý vector hoá với morsel-driven parallelism được để dành. Một cái kết treo hơi ác cho bài viết về một database.
Nhưng bài học của Phần 1 tự nó đứng vững. Chúng ta đổ biết bao công sức làm engine query khôn hơn - thứ tự join tốt hơn, optimizer chặt hơn, cắt tỉa thông minh hơn. DuckDB cũng làm hết mấy thứ đó. Nhưng cú tăng tốc lớn nhất của nó lại đến từ một chuyện đơn giản: request mạng nhanh nhất là cái request bạn không bao giờ phải gửi.
Các Kiến Trúc Cơ Sở Dữ Liệu & Hệ Thống Liên Quan
Nếu anh em đang đào sâu về hiệu năng database, kiến trúc phi mạng (in-process) và tối ưu dữ liệu, hãy đọc tiếp các bài phân tích cùng chủ đề:
- PG Durable: Biến Postgres Thành Engine Chạy Workflow Bền Vững: Chạy tác vụ durable ngay trong PostgreSQL mà không cần dựng cụm Temporal hay Redis cồng kềnh.
- ZeroStack: AI Coding Agent Bằng Rust Chỉ Tốn 8MB RAM: Cắt bỏ bloatware từ tận gốc tiến trình — binary native siêu nhẹ không tốn tài nguyên runtime.
- Context Hub: Kho Tài Liệu Tinh Gọn Cho Coding Agent: Tối ưu dữ liệu đầu vào cho AI mà không bị nghẽn mạng hay tràn context window.
- Pi Mono Explained: Kiến Trúc Autonomous AI Coding Agent: Tìm hiểu cách thiết kế các module cốt lõi cho một runtime tự hành hiệu năng cao.
Thảo luận trên Hacker News · Nguồn: greybeam.ai · Đăng bởi marklit
Bài viết liên quan
Java Valhalla: Mười Hai Năm Để Xóa Một Giả Định
Sau một thập kỷ, Project Valhalla cuối cùng đã vào JDK 28 dạng preview. Cả dự án rút lại còn một ý: cho phép object từ bỏ identity để JVM xếp gọn như int.
AutoResearch Giải Thích: Vì Sao Karpathy Đóng Góp Cho AI Scientist Này
Mổ xẻ AutoResearch: kiến trúc AI scientist đa mô hình, cơ chế Ralph loop hồi phục trạng thái và lý do Karpathy trực tiếp đóng góp vào repo.
Những thuật ngữ thượng đẳng để coding với AI Agent sướng hơn
Khám phá các thuật ngữ kiến trúc và kỹ thuật lập trình đòn bẩy cao giúp bạn prompt AI Coding Agent chính xác, loại bỏ ảo giác và viết code chuẩn senior.
AI Agent Book Giải Thích: Lộ Trình Dễ Hiểu Cho Người Mới Từ Nền Tảng Đến Thực Chiến
Hướng dẫn thực chiến về ai-agent-book: kiến trúc cốt lõi, cách học từ cơ bản đến nâng cao, và lộ trình 2 tuần làm chủ AI Agent.