- DuckDB คือ โอเพนซอร์ส SQL เอนจิน ที่สามารถประมวลผลข้อมูลตารางขนาดใหญ่บนเครื่องเดียวได้อย่างรวดเร็วและเรียบง่าย และกำลังถูกใช้อย่างแพร่หลายในงานวิศวกรรมข้อมูลช่วงหลัง
- ติดตั้งง่าย ไม่มี dependency และสามารถรันได้ทันทีในสภาพแวดล้อม Python จึงเหมาะกับ CI และการทดสอบอัตโนมัติ
- ด้วย การปรับแต่งคิวรีเชิงวิเคราะห์ให้เหมาะสม ทำให้มีประสิทธิภาพเร็วกว่า SQLite หรือ Postgres ได้สูงสุดถึง 1,000 เท่า และสามารถคิวรีไฟล์รูปแบบต่าง ๆ (
csv, parquet, json) ได้โดยตรง
- มีทั้ง ไวยากรณ์ SQL ที่เป็นมิตร (
EXCLUDE, COLUMNS, QUALIFY, function chaining ฯลฯ) และ Python API ที่ช่วยให้พัฒนา pipeline ที่ซับซ้อนได้อย่างมีประสิทธิภาพ
- ด้วยคุณสมบัติอย่าง รองรับ ACID, UDF ประสิทธิภาพสูง, และ ส่วนขยายสำหรับเชื่อมต่อ PostgreSQL ทำให้กำลังกลายเป็น ทางเลือกแทน lakehouse สำหรับข้อมูลขนาดกลาง
ภาพรวมของ DuckDB
- DuckDB คือ in-process SQL engine ที่เน้นการ ปรับแต่งคิวรีเชิงวิเคราะห์
- ทำงานภายในแอปพลิเคชันได้โดยไม่ต้องมีเซิร์ฟเวอร์แยก และไม่ต้องพึ่งบริการภายนอกอย่าง Postgres
- ถูกออกแบบมาสำหรับงาน join และ aggregate ปริมาณมาก และให้ประสิทธิภาพเร็วกว่าเอนจินที่เน้นธุรกรรม (OLTP) ได้สูงสุด 100~1,000 เท่า
- กรณีใช้งานหลักคือการอ่านไฟล์ขนาดใหญ่ เช่น
csv, parquet, json จากดิสก์โดยตรงเพื่อทำ batch processing
- ยังเหมาะสำหรับ การสำรวจข้อมูลแบบเบา ๆ เช่น เปิดดูไฟล์ CSV จาก command line อย่างง่าย
คุณสมบัติเด่น
-
ความเร็ว
- DuckDB เป็น หนึ่งในเอนจินประมวลผลข้อมูลโอเพนซอร์สที่เร็วที่สุด และติดอันดับต้น ๆ ใน benchmark อย่างต่อเนื่อง
- เมื่อเทียบกับ Polars, DataFusion, Spark, Dask ฯลฯ DuckDB เด่นกว่าในข้อมูลขนาดเล็ก ส่วนข้อมูลขนาดใหญ่ Spark และ Dask ยังแข่งขันได้
-
ติดตั้งง่ายและไม่มี dependency
- DuckDB ถูกแจกจ่ายในรูปแบบ ไบนารีที่คอมไพล์ล่วงหน้าไฟล์เดียว และใน Python สามารถติดตั้งได้ทันทีด้วย
pip install duckdb
- ด้วยความที่ ไม่มี dependency การติดตั้งจึงง่ายกว่ามากเมื่อเทียบกับเฟรมเวิร์กขนาดใหญ่อย่าง Spark
- เมื่อใช้ร่วมกับ
uv สามารถ ตั้งค่าสภาพแวดล้อม Python ได้ภายในไม่ถึง 1 วินาที
-
CI และการทดสอบ
- ด้วย การเริ่มต้นที่รวดเร็วและความเบา จึงเหมาะกับ สภาพแวดล้อม CI และการทดสอบ ของ data pipeline
- ในอดีตการทดสอบบน Spark ช้าและซับซ้อน แต่ DuckDB ช่วยให้ ตั้งค่าสภาพแวดล้อมได้ง่ายขึ้น และ รักษาความสอดคล้องกับ production ได้สะดวก
-
ประสบการณ์ในการเขียน SQL
- DuckDB ช่วยให้ เขียน SQL และตรวจสอบไวยากรณ์ ได้อย่างรวดเร็ว
- เหมาะกับการ รันทันทีและพัฒนาแบบวนซ้ำ มากกว่า Spark local mode หรือ AWS Athena
- มี UI ที่รองรับระบบ autocomplete
-
ไวยากรณ์ SQL ที่เป็นมิตร
- DuckDB มี ส่วนขยาย SQL ที่เป็นมิตรกับผู้ใช้ จำนวนมาก
- รองรับ
EXCLUDE, COLUMNS, QUALIFY, window function aggregate modifiers, function chaining (first_name.lower().trim()) เป็นต้น
- ความสามารถเหล่านี้ช่วยให้ การเลือกและแปลงคอลัมน์ที่ซับซ้อน เขียนได้กระชับขึ้น
-
รองรับไฟล์หลายรูปแบบ
- สามารถคิวรีข้อมูลได้โดยตรงจาก S3, เว็บ URL, ไฟล์ในเครื่อง เป็นต้น
- มี ตัวเลือกความเข้มงวดของชนิดข้อมูลใน CSV เพื่อป้องกันข้อผิดพลาดจากข้อมูลนำเข้าที่ไม่มีโครงสร้างชัดเจน
-
Python API
- ใน Python สามารถกำหนด pipeline แบบอิง CTE ทีละขั้น และตรวจสอบข้อมูลของแต่ละขั้นได้อย่างง่ายดาย
- เชื่อม SQL แบบ chain ได้ผ่านการเรียก
duckdb.sql()
- ด้วย lazy execution จึงตรวจสอบผลลัพธ์ระหว่างทางได้โดยไม่เสียประสิทธิภาพ
- สามารถทดสอบฟังก์ชันในแต่ละขั้นได้ ทำให้ การทดสอบใน CI มีประสิทธิภาพยิ่งขึ้น
-
รองรับ ACID
- DuckDB รับประกัน ACID อย่างสมบูรณ์ แม้ในงานกับข้อมูลปริมาณมาก
- คุณสมบัตินี้ทำให้สามารถใช้เป็น ทางเลือกขนาดกลาง สำหรับฟอร์แมต lakehouse อย่าง Iceberg และ Delta Lake ได้
-
UDF ประสิทธิภาพสูงและส่วนขยายจากชุมชน
- สามารถเขียน user-defined function (UDF) ประสิทธิภาพสูง ด้วย C++ ได้
- ผ่าน Community Extensions สามารถติดตั้งส่วนขยายได้ทันทีด้วยคำสั่งอย่าง
INSTALL h3 FROM community
- ตัวอย่างเช่น รองรับ ดัชนีหกเหลี่ยมสำหรับข้อมูลเชิงพื้นที่ (h3)
-
เอกสาร
- เอกสารถูกจัดให้ในรูปแบบ ไฟล์ Markdown เดียว ทั้งหมด ทำให้สะดวกต่อ การฝึก LLM หรือการค้นหาในโค้ดเอดิเตอร์
- มีฟังก์ชัน code folding ช่วยให้คัดลอกเฉพาะส่วนที่ต้องการได้ง่าย
การใช้งานจริงและผลลัพธ์
- ในโปรเจกต์โอเพนซอร์ส Splink เมื่อเลือกใช้ DuckDB เป็นแบ็กเอนด์หลัก
- ก็สามารถบรรลุทั้ง การลดปัญหาของผู้ใช้, เพิ่มความเร็วในการทำงาน, และ ทำให้การพัฒนาฟีเจอร์และการทดสอบง่ายขึ้น
ส่วนขยายที่น่าจับตา
- PostgreSQL Extension: เชื่อมต่อและคิวรีฐานข้อมูล Postgres ได้โดยตรงจาก DuckDB
- pg_duckdb: ฝังเอนจิน DuckDB ไว้ภายใน Postgres เพื่อให้ ประมวลผลธุรกรรมและงานวิเคราะห์ควบคู่กันได้
- ในอนาคตหากมีการปรับปรุง การเพิ่มประสิทธิภาพดัชนีของ Postgres และ filter push-up ก็มีโอกาสถูกนำไปใช้อย่างแพร่หลาย
2 ความคิดเห็น
มันก็น่าขันดีนะที่ใช้
parqซึ่งมีไว้สำหรับการประมวลผลแบบกระจาย มาเพื่อประมวลผลบนเครื่องเดี่ยวความคิดเห็นบน Hacker News
มีหลายเหตุผลที่ผมชอบ DuckDB
รองรับทั้งไฟล์
.parquet,.json,.csvและสามารถ อ่านแบบ glob ได้ เช่นselect * from 'tsa20*.csv'ทำให้จัดการไฟล์หลายร้อยไฟล์เหมือนเป็นไฟล์เดียวได้ถึงสคีมาจะต่างกันก็รวมกันได้ง่ายด้วย
union_by_nameและ ตัวแยกวิเคราะห์ CSV ก็เดาประเภทข้อมูลให้อัตโนมัติได้ดีเวอร์ชัน WebAssembly มีขนาด 2MB และ CLI มีขนาด 16MB เล็กมาก
จึงสามารถฝังเข้าไปในโปรดักต์ได้โดยตรง เช่น Malloy
Malloy คล้าย PowerBI หรือ Tableau เวอร์ชันสำหรับสายเทคนิค โดยใช้ semantic model เพื่อช่วยให้ AI เขียนคิวรีได้ดีขึ้น ให้ความรู้สึกเหมือนทำให้ SQL เขียนง่ายขึ้น 10 เท่า
เมื่อก่อนผมต้องเสียเวลาทำความเข้าใจสคีมาก่อน แต่ตอนนี้ผมโหลดข้อมูลเข้ามา เขียน exploratory query ตรวจสอบสมมติฐาน แล้ววนทำขั้นตอนทำความสะอาด แปลงข้อมูล และสร้างตาราง
ทำให้เจาะลึกได้เร็วขึ้นมาก และยังเจอ ทางตัน ได้ไวขึ้น จึงเสียเวลาน้อยลง
เคยได้ยินว่ามีงานวิจัยที่อธิบายวิธีทำงานของตัวแยกวิเคราะห์ CSV และไอเดียการปรับปรุงในอนาคต แต่ยังหาไม่เจอ
โดยเฉพาะการ ingest Parquet และ JSON ที่สะดวก และ
clickhouse-localก็คล้ายกับแนวคิดการฝัง DuckDBใช้ไวยากรณ์
SELECT ... FROM s3Cluster(...)เพื่อ ingest แบบ wildcard จากบัคเก็ต S3 ได้ และกระจายงานไปยังโหนดในคลัสเตอร์ดูเหมือนว่าจะรองรับ
schema_inference_modeด้วยClickHouse ก็ทำฟีเจอร์คล้าย
union_by_nameมาแล้วเอกสารที่เกี่ยวข้อง: ฟังก์ชัน s3Cluster, schema inference, PR #55892
แต่ Shaper ใช้ SQL แทนการมีภาษาแยกต่างหาก
สามารถสร้าง แดชบอร์ดด้วย SQL ล้วนๆ บนพื้นฐานของ DuckDB ได้
Shaper GitHub
มันเร็วมากอย่างน่าทึ่ง และ การตรวจจับสคีมาอัตโนมัติ ก็ทำงานได้ถูกต้องเกือบตลอด
LLM สามารถสร้าง SQL ที่ถูกต้องจากคำถามภาษาธรรมชาติได้
ปกติผมใช้วิธี import เข้า SQLite แบบแมนนวล แต่ DuckDB ทำให้ทุกอย่างง่ายขึ้นมาก
ผมเองก็เป็นคนที่ใช้ DuckDB เป็นประจำ
ผมทำงานกับนักวิทยาศาสตร์ที่ศึกษาสภาพแวดล้อมชายฝั่งของ BC และรับมือกับข้อมูลปริมาณมหาศาลตั้งแต่ การสังเกตการณ์ธารน้ำแข็งไปจนถึงข้อมูลโดรนน้ำลึก
เราเลือก DuckDB เป็นเอนจินของเครื่องมือแปลงข้อมูลความหลากหลายทางชีวภาพตัวใหม่ โดยมีเป้าหมายเพื่อแปลงและตรวจสอบข้อมูลตาม มาตรฐาน Darwin Core
เราสร้างตาราง DuckDB แบบไดนามิกจากสคีมาแล้ว import ข้อมูลเข้าไป ถ้าล้มเหลวก็จะแจ้งเหตุผลเป็นรายแถว
การแปลงและการตรวจสอบทั้งหมดก็ทำภายใน DuckDB
ด้วยเหตุนี้เราจึงสร้างแอปที่เร็วขึ้น ทรงพลังกว่าเดิม และ รันในเบราว์เซอร์ได้ด้วย
นักวิจัยภาคสนามจึงสามารถใช้งานแบบออฟไลน์บนเบราว์เซอร์ iPad ได้
DuckDB ทำให้ผมรู้สึกมั่นใจว่า SQL จะจัดการงานหนักให้เอง
ส่วนที่ยังขาดเรื่อง type safety เราก็ชดเชยด้วยการ parse และการทดสอบ
โปรเจกต์นี้มีเป้าหมายเพื่อให้นักวิทยาศาสตร์สามารถ วิเคราะห์ข้อมูลความหลากหลายทางชีวภาพและจีโนมด้วยเครื่องมือร่วมกัน และเผยแพร่สู่คลังสาธารณะ ได้
ผมทำงานกับข้อมูลวิทยาศาสตร์และต้องเจอ HDF5 บ่อยมาก แต่ DuckDB ยังไม่รองรับ HDF5 โดยตรง
ส่วน extension ที่มีอยู่ก็ช้าและความสามารถยังไม่พอ ผมเลยสร้าง extension ใหม่ด้วย C++ template
กำลังมองหาคนที่สนใจร่วมพัฒนา
ส่วนตัวผมรู้สึกว่าไวยากรณ์ของ Polars ใช้ง่ายกว่า SQL มาก เลยยังลังเลว่าคุ้มไหมที่จะลอง DuckDB
เราใช้ DuckDB สำหรับงานวิเคราะห์และประมวลผลฟีดของ Bluesky
เพื่อให้ได้ผลลัพธ์เร็ว เราใช้ Apache Arrow interface และใช้ SQG เพื่อสร้างโค้ดจาก DuckDB SQL query ได้โดยตรง
อยากแนะนำโปรเจกต์ Java ชื่อ manifold-sql
มันช่วยให้เขียน DuckDB SQL แบบ type-safe และ inline ได้
ใส่ SQL ลงไปในโค้ดโดยตรงแล้ววนผลลัพธ์ได้ด้วย
.fetch()จึงสะอาดมากโดยไม่ต้องมีเลเยอร์กลางข้อเสนอของผู้เขียนฟังขึ้นสำหรับงานประมวลผลข้อมูลพื้นฐาน
แต่ประโยคที่ว่า “ข้อมูลตารางส่วนใหญ่ประมวลผลได้บนเครื่องเดียว” ยังเป็นประเด็นที่ถกเถียงได้
เพราะเวลาขยายข้อมูล ทำ pivot หรือ augment ข้อมูล ก็อาจเจอ หน่วยความจำหมด (OOM) ได้เร็วมาก
อีกทั้งคำกล่าวที่ว่า “SQL ควรเป็นตัวเลือกแรกของ data engineering แบบใหม่” ก็อาจไม่เหมาะกับงานวิเคราะห์ที่ซับซ้อน
dataframe API อย่าง Polars หรือ pandas ก็มีข้อดีมาก แต่ปัญหาคือ ecosystem ยังไม่เป็นมาตรฐาน ทำให้ต้องเขียน pipeline ใหม่อยู่บ่อยๆ
ข้อมูลส่วนใหญ่มีขนาดต่ำกว่า 10GB ดังนั้นเครื่องเดียวก็จัดการได้สบาย
หลายกรณีใช้ Spark เกินความจำเป็น
จุดยืนของผมคือ “ลอง DuckDB ก่อน” เพราะในเคสง่ายๆ มันเร็วและมีประสิทธิภาพมาก
SQL ดีสำหรับ pipeline แบบตรงไปตรงมา แต่เรื่องความอ่านง่ายก็แล้วแต่คน
สำหรับผมฝั่ง dataframe อ่านง่ายกว่ามาก
ฝั่ง ingestion อาจใช้ Python หรือ Scala กันมาก แต่ SQL จะไม่หายไปไหน
OOM น่าจะเป็นปัญหาเฉพาะกรณีสุดโต่ง
ในขณะที่ DuckDB ได้รับความสนใจมาก Polars กลับถูกประเมินค่าต่ำไป
ผมทำงานประมวลผลข้อมูลเยอะ และส่วนใหญ่ใช้ Polars
มันเร็วมาก และมีฟังก์ชันหลายอย่างที่แบบ pandas ทำได้แต่ SQL ทำได้ยาก
ยังใช้ Python function ได้ตรงๆ ด้วย
ต่อให้ DuckDB จะเร็วพอๆ กัน ผมก็ยังลังเลเพราะ SQL ดูมี ข้อจำกัดด้านการแสดงออก
เป็น standalone ด้วยจึงติดตั้งง่าย และแทบ ไม่ต้องจูนหรือมี learning curve เลย
ผมนำเข้า ไฟล์ Excel รูปแบบเละเทะ ที่สร้างจากเมนเฟรมด้วย DuckDB
โดยใช้ตัวเลือก
all_varcharและโหลดเสร็จในเวลาไม่ถึง 1 วินาทีขณะที่ Excel เองยังเปิดไฟล์ไม่เสร็จเลย
DuckDB ยอดเยี่ยมมาก แต่ การโหลด extension แบบไดนามิก ชนกับ code signing ทำให้ใช้งานในแอปเชิงพาณิชย์ได้ยาก
อีกทั้ง spatial extension ก็ใช้คอมโพเนนต์ LGPL จึงมีประเด็นด้านไลเซนส์
อยากให้สามารถ ประกอบฟีเจอร์เป็นแพ็กเกจย่อย ได้แบบ Apache Arrow โดยเลือกเฉพาะส่วนที่ต้องใช้
เช่น ส่งอาร์เรย์ผ่าน HTTP ระดับ GB/s ใช้ Arrow Flight, แชร์ไฟล์ใช้ Arrow IPC, อ่าน Parquet ก็เพิ่ม trait แยกต่างหาก
ระบบชนิดข้อมูล SQL ของ DuckDB ต่างจาก Arrow จึงอาจเกิดปัญหา type mismatch ได้
ส่วน Arrow มี native library ให้เกือบทุกภาษา
ผมสงสัยว่าถ้ามีตารางเดียวที่มีข้อมูลธุรกรรมหลายพันล้านแถว (30 คอลัมน์)
จะสามารถดึงหน้าเพจที่ถูกกรองด้วยเงื่อนไข WHERE ได้เร็วไหม
บน Postgres แค่ count(*) ธรรมดาก็ใช้เวลานานแล้ว
เคสที่ช้ามีแค่ตอน join ซับซ้อนหรือประมวลผลหลายไฟล์แบบ glob เท่านั้น
ถ้าเงื่อนไข WHERE เป็นคู่คอลัมน์-ค่าที่เรียบง่าย ก็น่าจะทำได้เร็วพอสมควร
DuckDB ไม่ได้เป็นแค่ฐานข้อมูลที่เร็ว แต่ยังมี ประสบการณ์นักพัฒนา (devx) ที่ยอดเยี่ยม
เริ่มต้นได้ง่าย จึงทำให้ ecosystem เติบโตอย่างรวดเร็ว
การผสานกับ Web/WASM ก็น่าประทับใจมาก
อยากให้มี เอนจินขนาดเล็ก แบบนี้เกิดขึ้นอีกเยอะๆ เพื่อให้เกิดการแข่งขันและนวัตกรรมต่อไป