Nếu bạn cần phân tích dữ liệu lớn mà không muốn cài đặt database server phức tạp, DuckDB là câu trả lời. DuckDB là embedded analytical database — chạy trong cùng process với ứng dụng, không cần server riêng, nhưng xử lý truy vấn SQL nhanh hơn nhiều so với Pandas thuần.

Bài viết này giải thích DuckDB là gì, so sánh với SQLite/Pandas, và hướng dẫn sử dụng trong Python. Xem thêm Cache là gìAPI là gì — các khái niệm nền tảng trong hệ thống.

DuckDB là gì

DuckDB là một in-process analytical database (OLAP) được thiết kế cho workload phân tích dữ liệu. Khác với PostgreSQL hay MySQL cần chạy server riêng, DuckDB nhúng trực tiếp vào ứng dụng của bạn — giống SQLite nhưng tối ưu cho analytical queries thay vì transactional.

Đặc điểm chính

  • In-process — Không cần server, chạy trong cùng process với Python/Java/Node
  • Columnar storage — Lưu trữ theo cột, tối ưu cho aggregation, scan
  • Vectorized execution — Xử lý data theo batch, tận dụng SIMD CPU
  • Zero dependencies — Không cần cài đặt phức tạp, một file nhị phân
  • PostgreSQL-compatible syntax — Dùng SQL quen thuộc
  • Direct file query — Query trực tiếp CSV, Parquet mà không cần import

DuckDB vs SQLite vs Pandas

Ba công cụ này phục vụ mục đích khác nhau:

Tiêu chíDuckDBSQLitePandas
LoạiOLAP AnalyticalOLTP TransactionalDataFrame library
StorageColumnar, file-basedRow-based, file-basedIn-memory arrays
SQL supportFull SQLFull SQLLimited
Query Parquet/CSVDirect queryImport requiredImport required
Aggregation speedRất nhanhChậmTrung bình
Use caseAnalytics, BI, ETLApp data, mobileData wrangling

Benchmark thực tế: với 1 triệu rows, DuckDB nhanh hơn Pandas 10-50 lần cho các truy vấn aggregation phức tạp.

Cài đặt DuckDB

# Python
pip install duckdb

# R
install.packages("duckdb")

# Node.js
npm install duckdb

# Go
go get github.com/duckdb/duckdb-go

Sử dụng DuckDB trong Python

Kết nối và tạo bảng

import duckdb

# Tạo connection (file-based hoặc in-memory)
con = duckdb.connect('my_data.db')  # File database
# hoặc
con = duckdb.connect(':memory:')      # In-memory, không lưu

# Tạo bảng
con.sql('''
CREATE TABLE users (
    id INTEGER PRIMARY KEY,
    name VARCHAR,
    email VARCHAR,
    created_at DATE,
    salary DECIMAL(10,2)
)
''')

# Insert dữ liệu
con.sql("INSERT INTO users VALUES (1, 'Nguyen Van A', 'a@example.com', '2024-01-15', 1500)")
con.sql("INSERT INTO users VALUES (2, 'Tran Thi B', 'b@example.com', '2024-02-20', 2000)")

Query dữ liệu

# Query đơn giản
result = con.sql("SELECT * FROM users WHERE salary > 1500").fetchall()
print(result)

# Query với aggregation
avg_salary = con.sql("SELECT AVG(salary) as avg_salary FROM users").fetchone()
print(f"Average salary: {avg_salary[0]}")

# Query với GROUP BY
by_month = con.sql('''
SELECT 
    strftime(created_at, '%Y-%m') as month,
    COUNT(*) as count,
    AVG(salary) as avg_salary
FROM users
GROUP BY month
ORDER BY month
''').fetchall()
print(by_month)

Query trực tiếp CSV/Parquet

Đây là tính năng mạnh nhất của DuckDB — query file mà không cần import:

# Query CSV trực tiếp
result = con.sql('''
SELECT customer_id, SUM(amount) as total
FROM read_csv_auto('transactions.csv')
WHERE date >= '2024-01-01'
GROUP BY customer_id
''').fetchall()

# Query Parquet (nhanh hơn CSV)
result = con.sql('''
SELECT product_id, COUNT(*) as orders
FROM read_parquet('orders.parquet')
WHERE status = 'completed'
GROUP BY product_id
ORDER BY orders DESC
LIMIT 10
''').fetchall()

# Join nhiều files
result = con.sql('''
SELECT o.order_id, c.name, o.amount
FROM read_parquet('orders/*.parquet') o
JOIN read_csv('customers.csv') c ON o.customer_id = c.id
''').fetchall()

Tạo bảng từ Pandas DataFrame

import pandas as pd

# Tạo DataFrame
df = pd.DataFrame({
    'name': ['A', 'B', 'C'],
    'value': [100, 200, 300]
})

# Đăng ký DataFrame như view trong DuckDB
con.sql("CREATE VIEW my_df AS SELECT * FROM df")

# Hoặc tạo bảng từ DataFrame
con.sql("CREATE TABLE my_table AS SELECT * FROM df")

# Query bình thường
result = con.sql("SELECT * FROM my_df WHERE value > 150").fetchdf()
print(result)

Export kết quả

# Export to Parquet
con.sql("COPY (SELECT * FROM users) TO 'users.parquet' (FORMAT PARQUET)")

# Export to CSV
con.sql("COPY (SELECT * FROM users) TO 'users.csv' (HEADER TRUE)")

# Export to DataFrame
df_result = con.sql("SELECT * FROM users WHERE salary > 1500").fetchdf()
print(df_result)

Performance tips

  • Filter sớm — WHERE clause trước JOIN để giảm data
  • Chọn cột cần thiết — SELECT cột cụ thể thay vì SELECT *
  • Dùng Parquet — Parquet nhanh hơn CSV 5-10 lần cho analytical queries
  • Partition data — Chia data theo date để query nhanh hơn
# Tốt: filter trước, chỉ đọc partition cần
con.sql('''
SELECT product_id, SUM(amount)
FROM read_parquet('orders/2024/*.parquet')
WHERE status = 'completed'
GROUP BY product_id
''')

# Chậm hơn: đọc tất cả rồi filter
con.sql('''
SELECT product_id, SUM(amount)
FROM read_parquet('orders/*.parquet')
WHERE status = 'completed' AND year = 2024
''')

Use cases phổ biến

1. Data Analysis cục bộ

Phân tích log files, CSV exports, data dumps mà không cần setup database server. Chỉ cần cài DuckDB, đọc file, query.

2. ETL Pipeline

Transform dữ liệu từ nhiều nguồn (CSV, Parquet, JSON) vào một data warehouse cục bộ trước khi load lên cloud.

# ETL example
con.sql('''
CREATE TABLE aggregated AS
SELECT 
    date,
    product_category,
    COUNT(*) as orders,
    SUM(amount) as revenue,
    AVG(amount) as avg_order_value
FROM (
    SELECT * FROM read_csv_auto('orders_2024.csv')
    UNION ALL
    SELECT * FROM read_parquet('orders_legacy/*.parquet')
)
GROUP BY date, product_category
''')

3. Embedded Analytics

Nhúng trực tiếp vào ứng dụng Python để cung cấp analytical capabilities mà không cần backend database riêng.

4. BI Tool Backend

Dùng làm fast analytical backend cho các BI tools đơn giản, thay thế việc query trực tiếp production database.

So sánh DuckDB với các database khác

DatabaseLoạiServerBest for
DuckDBOLAPEmbeddedLocal analytics, data processing
SQLiteOLTPEmbeddedApp storage, mobile
PostgreSQLOLTP/OLAPServerProduction apps
SnowflakeOLAPCloudEnterprise data warehouse
ClickHouseOLAPServer/CloudReal-time analytics

Câu hỏi thường gặp

DuckDB có thay thế PostgreSQL không?

Không. DuckDB là embedded analytical database, không phải general-purpose transactional database. Dùng PostgreSQL cho production apps, dùng DuckDB cho analytics và data processing.

DuckDB dùng bao nhiêu RAM?

Mặc định DuckDB sử dụng tất cả RAM có sẵn cho caching. Có thể giới hạn bằng SET memory_limit='4GB'.

Có thể dùng DuckDB cho production không?

DuckDB được thiết kế cho single-node analytical workloads. Cho production với nhiều concurrent users, nên dùng PostgreSQL, ClickHouse, hoặc cloud data warehouse.

DuckDB hỗ trợ concurrent writes không?

Hạn chế. DuckDB là single-writer database. Cho concurrent writes, cần dùng database server khác.

Tham khảo

Tài liệu chính thức: DuckDB Documentation. Tìm hiểu thêm về benchmark tại KDnuggets Benchmark.

Kết luận

DuckDB là công cụ mạnh mẽ cho phân tích dữ liệu cục bộ. Nếu bạn đang dùng Pandas để xử lý data lớn và thấy chậm, thử DuckDB — bạn sẽ ngạc nhiên với tốc độ. Đặc biệt hữu ích khi:

  • Cần query trực tiếp CSV/Parquet mà không import
  • Phân tích data dump hoặc log files cục bộ
  • Build ETL pipeline đơn giản
  • Prototype analytical features trước khi deploy lên production database

Thử ngay với pip install duckdb và bắt đầu query!

Chào các bạn mình là Quốc Hùng , mình sinh ra thuộc cung song tử ,song tử luôn khẳng định chính mình ,luôn luôn phấn đấu vượt lên phía trước ,mình sinh ra và lớn lên tại vùng đất võ cổ truyền ,đam mê của mình là coder ,ngày đi học tối về viết blog ...