左优扬 发表于 2026-1-4 00:50:03

[OLAP] DuckDB : 开源免费的、面向嵌入式场景、列式存储的分析型数据库

0 序


[*]DuckDB 是近期非常火的一款 AP 数据库,其独特的定位很有趣。甚至有数据库产品考虑将其纳入进来,作为分析能力的扩展。
考虑到项目中一个数据处理场景,就此调研一二。


[*]DuckDB 的爆火,也给所有盲目追逐“大数据”的技术人敲响了警钟:


[*]DuckDB 是一场复古的叛逆,也是一场属于单机的复仇。它告诉我们:在算力爆炸的今天,小,即是快;简,即是强。
[*]我们被云厂商和大数据鼓吹者洗脑太久了,总觉得不搞个集群、不弄个微服务,架构就不够“高大上”。但技术的本质是解决问题,而不是制造复杂度。


[*]重要结论:


[*]DuckDB := 数据分析领域的 SQLLite (列式存储)
适合分析 / 列压缩 / 每一列在磁盘和内存中以分块数组的形式存储
内存局部性优化 / 读取查询速度更快


[*]适用于:单机/嵌入式场景
物联网/移动端/个人PC端/中小企业(TB级以下数据场景,尤其是数百GB级以下)
1 概述:DuckDB

DuckDB 介绍

产品定位与产生背景


[*]DuckDB 是一个诞生于2018年,开源免费的、面向嵌入式场景的、列式存储的、In-Process 的 OLAP 数据库。


[*]产生背景:2019 年, SIGMOD 有一篇 Demo 论文介绍 DuckDB:an embedded analytical database。随着单机内存的变大,大部分 OLTP 数据库都能在内存中放得下,而很多 OLAP 也有在单机就能搞定的趋势。单台服务器的内存很容易达到 TB,加上 SSD,搞个几十甚至上百 TB 很容易。DuckDB 就是为了填补这个空白而生的。
[*]定位:一款单机版/嵌入式分析型数据库 (数据分析领域的 SQLLite,但其底层是列式存储)
[*]Slogan : DuckDB 是一个分析式的 SQL 数据库管理系统
[*]https://github.com/duckdb/duckdb


[*]主要编程语言: C/C++


[*]支持多种数据格式的导入与导出:


[*]csv / excel / json / parquet 等本地文件格式
[*]http(s) / s3 等远程文件格式
开源情况


[*]DuckDB 采用 较为宽松的 MIT 协议开源。
其作为荷兰 CWI 数据库组的一个项目,学术气息比较浓厚,项目的组织很有教科书的感觉,架构很清晰,所以非常适合阅读学习。
从 OSS Insight 拉个一个 Star 数对比,可以看到 DuckDB 发展非常迅速。
https://ossinsight.io/analyze/duckdb/duckdb#overview

DuckDB 主要特点


[*]DuckDB是一个免费的、开源的、面向单机的(嵌入式/非分布式的)数据库管理系统,专为【数据分析】和【在线分析处理】而设计。
这意味着以下几点:


[*]它是免费的开源软件,因此任何人都可以使用和修改代码。
[*]它是面向单机的/嵌入式的。
这意味着DBMS(数据库管理系统)与使用它的应用程序在同一进程中运行。这使得它快速且易于使用。


[*]它针对【数据分析】和【OLAP】(在线分析处理)进行了优化,而不仅仅是像典型数据库那样只针对事务数据。
这意味着数据【按列】而不是【按行】组织以优化聚合和分析。


[*]它支持【标准SQL】,因此可以在数据上运行查询、聚合、连接和其他SQL函数。
[*]它在【进程中运行】,即在应用程序本身内运行,而不是作为单独的进程运行。这消除了进程间通信的开销。
与SQLite一样,它是一个简单的、基于文件的数据库。因此,不需要单独安装服务器。只需将库包含在应用程序中即可。
主要优点


[*]易于安装、部署和使用。没有需要配置的服务器,可在应用程序内部嵌入运行,这使得它易于集成到不同编程语言环境中。
[*]尽管它很简单,但DuckDB具有丰富的功能集。它支持完整的SQL标准、事务、二级索引,并且与流行的数据分析编程语言如 Python 和 R 集成良好。
[*]免费的,任何人都可以使用和修改它,这降低了开发人员和数据分析师采用它的门槛。
[*]兼容性很好,几乎无依赖性,甚至可在浏览器中运行。
[*]具有灵活的扩展机制,这对于直接从 CSV、JSON、Parquet、MySQL 或直接从 S3 读取数据特别重要,能够大大提高开发人员的体验。
[*]可提供数据超出内存限制但小于磁盘容量规模下的工作负载,这样分析工作可通过 "便宜"的硬件来完成。
2 安装部署篇


[*]DuckDB 安装部署过程相当简单,且支持多种部署模式:

CLI / Python / Go / Java / Nodejs / C/C++ / R / Rust / ODBC
简言之,DuckDB 提供了非常简单的安装方法,可从官网 https://duckdb.org/install/ 直接下载安装解压即可使用。此外,DuckDB 还可以内置在多种开发语言中使用。
安装 CLI by Windows(Powershell)

DuckDB 可以通过 PSDuckDB 模块与 PowerShell 无缝集成,从而实现从 PowerShell 环境中高效执行分析性 SQL 查询。


[*]以管理员权限打开 PowerShell :
PS C:\Windows\system32> Install-Module PSDuckDB                                                                                                                                                                                                                                                                                                         需要使用 NuGet 提供程序来继续操作
PowerShellGet 需要使用 NuGet 提供程序“2.8.5.201”或更高版本来与基于 NuGet 的存储库交互。必须在“C:\Program
Files\PackageManagement\ProviderAssemblies”或“C:\Users\EDY\AppData\Local\PackageManagement\ProviderAssemblies”中提供 NuGet 提供程序。也可以通过运行
'Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force' 安装 NuGet 提供程序。是否要让 PowerShellGet 立即安装并导入 NuGet 提供程序?
是(Y) 否(N) 暂停(S)[?] 帮助 (默认值为“Y”): Y

不受信任的存储库
你正在从不受信任的存储库安装模块。如果你信任该存储库,请通过运行 Set-PSRepository cmdlet 更改其 InstallationPolicy 值。是否确实要从“PSGallery”安装模块?
是(Y) 全是(A) 否(N) 全否(L) 暂停(S)[?] 帮助 (默认值为“N”): Y

PS C:\Windows\system32>

[*]安装完成后,输入 psduckdb 即可使用
PS C:\Windows\system32> psduckdb
Welcome to PSDuckDB! 01/02/2026 09:02:51
Connected to an in-memory database
PSDuckDB: show databases;

database_name
-------------
memory


PSDuckDB: show tables
PSDuckDB: select 1 as tmp_a

tmp_a
-----
    1

PSDuckDB:
PSDuckDB: exit
PS C:\Windows\system32>安装 CLI by Windows(解压即安装)


[*]下载后解压 zip 安装包,双击打开 duckdb.exe 即可使用
https://duckdb.org/install/?platform=windows&environment=cli

[*]duckdb_cli-windows-amd64.zip
[*]duckdb_cli-windows-arm64.zip
D:\Program\DuckDB-CLI\duckdb.exe

3 工作原理与架构篇

数据库架构



[*]DuckDB 数据库可分为多个组件:Parser、Logical Planner、Optimizer、Physical Planner、Execution Engine、Transaction and Storage Managers
Parser


[*]DuckDB SQL Parser 源自 Postgres SQL Parser。
Logical Planner


[*]其包含了两个过程 binder、plan generator。前者是解析所有引用的 schema 中的对象(如 table 或 view)的表达式,将其与列名和类型匹配。后者将 binder 生成的 AST 转换为由基本 logical query 查询运算符组成的树,就得到了一颗 type-resolved logical query plan。
Optimizer

优化器部分,会采用多种优化手段对 logical query plan 进行优化,最终生成 physical plan。例如,其内置一组 rewrite rules 来简化 expression tree,例如执行公共子表达式消除和常量折叠。针对表关联,会使用动态规划进行 join order 的优化,针对复杂的 join graph 会 fallback 到贪心算法会消除所有的 subquery。
Execution Engine

DuckDB 最开始采用了基于 Pull-based 的 Vector Volcano 的执行引擎,后来切换到了 Push-based 的 pipelines 执行方法。DuckDB 采用了向量化计算来来加速计算,具有内部实现的多种类型的 vector 以及向量化的 operator。另外出于可移植性原因,没有采用 JIT,因为 JIT引擎依赖于大型编译器库(例如LLVM),具有额外的传递依赖。
Transactions

DuckDB 通过 MVCC 提供了 ACID 的特性,实现了HyPer专门针对混合OLAP OLTP系统定制的可串行化MVCC 变种 。该变种立即 in-place 更新数据,并将先前状态存储在单独的 undo buffer 中,以供并发事务和 abort 使用。
Persistent Storage

DuckDB 使用面向读取优化的 DataBlocks 存储布局(单个文件)。逻辑表被水平分区为 chunks of columns,并使用轻量级压缩方法压缩成 physical block 。每个块都带有每列的min/max 索引,以便快速确定它们是否与查询相关。此外,每个块还带有每列的轻量级索引,可以进一步限制扫描的值数量。
4 使用指南篇

(本地)数据导入和导出


[*]推荐文献


[*]数据导入概述 - DuckDB 【推荐】


[*]支持的数据导入与导出场景


[*]CSV 导入
SELECT * FROM read_csv('input.csv');

[*]CSV 导出
COPY tbl TO 'output.csv' (HEADER, DELIMITER ',');

[*]直接读取文件
SELECT
    size, parse_path(filename), content
FROM read_text('test/sql/table_function/files/*.txt');

[*]Excel 导入
SELECT * FROM read_xlsx('test_excel.xlsx');

[*]Excel 导出
COPY tbl TO 'output.xlsx' WITH (FORMAT xlsx);

[*]JSON 导入
SELECT * FROM read_json_auto('input.json');

[*]JSON 导出
# COPY (SELECT * FROM range(3) tbl(n)) TO 'output.json';
{"n":0}
{"n":1}
{"n":2}

# COPY (SELECT * FROM range(3) tbl(n)) TO 'output.json' (ARRAY);
[
      {"n":0},
      {"n":1},
      {"n":2}
]

[*]Parquet 导入
https://duckdb.org/docs/stable/guides/network_cloud_storage/http_import
SELECT * FROM read_parquet('input.parquet');
SELECT * FROM read_parquet('https://domain/path/to/file.parquet');
SELECT * FROM read_parquet('s3://{bucketName}/path/to/file.parquet');

[*]Parquet 导出
COPY (SELECT * FROM tbl) TO 'output.parquet' (FORMAT parquet);

[*]查询Parquet文件
SELECT * FROM read_parquet('input.parquet');

[*]文件访问:协议
DuckDB 支持使用该协议。目前支持以下格式:file:


[*]file:/some/path(host完全省略)
[*]file:///some/path(空主)
[*]file://localhost/some/path (localhost作为host)
请注意,以下格式不被支持,因为它们是非标准的:

[*]file:some/relative/path(相对路径)
[*]file://some/path(双斩路径)
此外,该协议目前不支持远程(非本地主机)主机。
Parquet 专章


[*]查看 parquet 文件的数据
D select * from read_parquet("D:\Program-Data\DuckDB\datasources\tb_demo.parquet") limit 10
col_0|col_1|col_2|col_3|
-----+-----+-----+-----+
    1|    2|    3|    4|
    5|    6|    7|    8|
    9|   10|   11|   12|
   13|   14|   15|   16|

[*]查询多个parquet文件的数据 (当数据结构(定义)一致时, 支持多个文件读.)
-- read 3 parquet files and treat them as a single table   
SELECT * FROM read_parquet(['file1.parquet', 'file2.parquet', 'file3.parquet']);WildcardDescription*matches any number of any characters (including none)?matches any single charactermatches one character given in the bracketmatches one character from the range given in the bracket-- read all files that match the glob pattern   
SELECT * FROM read_parquet('test/*.parquet');   

-- Read all parquet files from 2 specific folders   
SELECT * FROM read_parquet(['folder1/*.parquet','folder2/*.parquet']);

[*]查看 parquet 文件的元数据
文件路径 / 列名 / 列序 / 列类型 / 压缩算法(zstd / snappy / ...) / ...
D SELECT * FROM parquet_metadata("D:\Program-Data\DuckDB\datasources\tb_demo.parquet")
file_name                                       |row_group_id|row_group_num_rows|row_group_num_columns|row_group_bytes|column_id|file_offset|num_values|path_in_schema|type |stats_min|stats_max|stats_null_count|stats_distinct_count|stats_min_value|stats_max_value|compression|encodings               |index_page_offset|dictionary_page_offset|data_page_offset|total_compressed_size|total_uncompressed_size|key_value_metadata|bloom_filter_offset|bloom_filter_length|min_is_exact|max_is_exact|row_group_compressed_bytes|geo_bbox|geo_types|
--------------------------------------------------+------------+------------------+---------------------+---------------+---------+-----------+----------+--------------+-----+---------+---------+----------------+--------------------+---------------+---------------+-----------+--------------------------+-----------------+----------------------+----------------+---------------------+-----------------------+------------------+-------------------+-------------------+------------+------------+--------------------------+--------+---------+
D:\Program-Data\DuckDB\datasources\tb_demo.parquet|         0|               4|                  4|            476|      0|          0|         4|col_0         |INT64|1      |13       |               0|                  |1            |13             |SNAPPY   |PLAIN, RLE, RLE_DICTIONARY|               |                     4|            46|                  117|                  119|{}                |                   |                   |true      |true      |                         1|      |NULL   |
D:\Program-Data\DuckDB\datasources\tb_demo.parquet|         0|               4|                  4|            476|      1|          0|         4|col_1         |INT64|2      |14       |               0|                  |2            |14             |SNAPPY   |PLAIN, RLE, RLE_DICTIONARY|               |                   121|             163|                  117|                  119|{}                |                   |                   |true      |true      |                         1|      |NULL   |
D:\Program-Data\DuckDB\datasources\tb_demo.parquet|         0|               4|                  4|            476|      2|          0|         4|col_2         |INT64|3      |15       |               0|                  |3            |15             |SNAPPY   |PLAIN, RLE, RLE_DICTIONARY|               |                   238|             280|                  117|                  119|{}                |                   |                   |true      |true      |                         1|      |NULL   |
D:\Program-Data\DuckDB\datasources\tb_demo.parquet|         0|               4|                  4|            476|      3|          0|         4|col_3         |INT64|4      |16       |               0|                  |4            |16             |SNAPPY   |PLAIN, RLE, RLE_DICTIONARY|               |                   355|             397|                  117|                  119|{}                |                   |                   |true      |true      |                         1|      |NULL   |

[*]查询 parquet 文件的数据结构(定义)
-- fetch the column names and column types   
D DESCRIBE SELECT * FROM "D:\Program-Data\DuckDB\datasources\tb_demo.parquet";   
column_name|column_type|null|key|default|extra|
-----------+-----------+----+---+-------+-----+
col_0      |BIGINT   |YES |   |       |   |
col_1      |BIGINT   |YES |   |       |   |
col_2      |BIGINT   |YES |   |       |   |
col_3      |BIGINT   |YES |   |       |   |


-- fetch the internal schema of a parquet file   
D SELECT * FROM parquet_schema("D:\Program-Data\DuckDB\datasources\tb_demo.parquet");   
file_name                                       |name|type |type_length|repetition_type|num_children|converted_type|scale|precision|field_id|logical_type|duckdb_type|
--------------------------------------------------+------+-----+-----------+---------------+------------+--------------+-----+---------+--------+------------+-----------+
D:\Program-Data\DuckDB\datasources\tb_demo.parquet|schema|   |         |REQUIRED       |         4|            |   |         |      |            |         |
D:\Program-Data\DuckDB\datasources\tb_demo.parquet|col_0 |INT64|         |OPTIONAL       |            |            |   |         |      |            |BIGINT   |
D:\Program-Data\DuckDB\datasources\tb_demo.parquet|col_1 |INT64|         |OPTIONAL       |            |            |   |         |      |            |BIGINT   |
D:\Program-Data\DuckDB\datasources\tb_demo.parquet|col_2 |INT64|         |OPTIONAL       |            |            |   |         |      |            |BIGINT   |
D:\Program-Data\DuckDB\datasources\tb_demo.parquet|col_3 |INT64|         |OPTIONAL       |            |            |   |         |      |            |BIGINT   |

[*]将 parquet 文件的数据插入本地表
-- insert the data from the parquet file in the table   
INSERT INTO people SELECT * FROM read_parquet('test.parquet');   
   
-- create a table directly from a parquet file   
CREATE TABLE people AS SELECT * FROM read_parquet('test.parquet');   

-- or
COPY tbl FROM 'input.parquet' (FORMAT PARQUET);

[*]创建parquet文件视图
-- create a view over the parquet file   
CREATE VIEW people AS SELECT * FROM read_parquet('test.parquet');   
   
-- query the parquet file   
SELECT * FROM people;(远程)网络与云存储

S3 Parquet Import


[*]推荐文献


[*]S3 Parquet 导入 - DuckDB


[*]前提条件


[*]要从 S3 加载 Parquet 文件,需要 httpfs 扩展名。这可以通过SQL命令安装。这个程序只需要运行一次 INSTALL 命令:
INSTALL httpfs;


[*]要加载扩展以供使用,请使用SQL命令:
LOAD httpfs;

[*]凭据与配置
加载扩展后,设置凭证和S3区域读取数据:httpfs
-- 创建 SECRET
CREATE OR REPLACE SECRET s3_secret_qiniu ( -- or 持久化存储密钥: CREATE PERSISTENT SECRET s3_secret_qiniu (
    TYPE s3
    -- , PROVIDER config -- (可选配置项) 作用: 当遇到 s3: 协议的 http 文件时,默认使用此 secret
    , ENDPOINT 's3.cn-south-1.qiniucs.com' -- 's3.oss-cn-beijing.aliyuncs.com' (阿里云为例)
    , KEY_ID 'R534353545DrQp0ipYngKsey' -- 'AKIAIO3535355AMPLE'
    , SECRET '02xSD945454545gl4543535sD' -- 'wJalrXUtnF353535DENG/bPxRfiCYEXAMPLEKEY'
   
    -- , REGION 'cn-south-1' -- 如 'us-east-1' (可选配置项)
    -- , SCOPE 's3://{bucketName}' -- (可选配置项)
);

-- 查看 secret
SELECT * FROM duckdb_secrets();

-- 删除 secret
-- DROP SECRET s3_secret_qiniu; -- 或 删除持久化的密钥: DROP PERSISTENT SECRET s3_secret_qiniu;:注:默认情况下,会将持久化的密码信息(未加密)写入 ~/.duckdb/stored_secrets 目录。要更改秘密目录,请执行
SET secret_directory = 'path/to/my_secrets_dir';

[*]查询远程对象存储中指定 parquet 文件的数据
-- 从s3查询 parquet 文件的数据
select * from read_parquet('s3://{bucketName}/dataset/tb_demo.parquet')

/**
col_0|col_1|col_2|col_3|
-----+-----+-----+-----+
    1|    2|    3|    4|
    5|    6|    7|    8|
    9|   10|   11|   12|
   13|   14|   15|   16|
**/
参数管理


[*]查看参数
D select name,value from duckdb_settings();
name                                       |value
-------------------------------------------+-----
Calendar                                 |grego
TimeZone                                 |Asia/
access_mode                              |autom
allocator_background_threads               |false
allocator_bulk_deallocation_flush_threshold|512.0
allocator_flush_threshold                  |128.0
allow_community_extensions               |true
allow_extensions_metadata_mismatch         |false
allow_persistent_secrets                   |true
allow_unredacted_secrets                   |false
allow_unsigned_extensions                  |false
allowed_directories                        |[]   
allowed_paths                              |[]   
arrow_large_buffer_size                  |false
arrow_lossless_conversion                  |false
arrow_output_list_view                     |false
...
disabled_optimizers                        |   
duckdb_api                                 |jdbc
dynamic_or_filter_threshold                |50   
enable_curl_server_cert_verification       |true
...

[*]修改参数
D set threads=10;

[*]查看单个参数
D SELECT current_setting('threads') AS threads;
+---------+
| threads |
+---------+
| 10    |
+---------+Pragma 扩展


[*]PRAGMA 语句是DuckDB从SQLite中采用的SQL扩展。


[*]PRAGMA语句可以以与常规SQL语句类似的方式发出。
[*]PRAGMA命令可能会改变数据库引擎的内部状态,并可能影响引擎的后续执行或行为。
数据库信息


[*]数据库信息
-- 数据库信息
D PRAGMA database_list;
+------+------+---------------------------------------+
| seq| name |               file                  |
+------+------+---------------------------------------+
| 1080 | file | ...file.db                            |
+------+------+---------------------------------------+
或:
seq|name|file|
---+------+----+
592|memory|    |

[*]查看数据库信息(大小)
-- 数据库信息(大小)
D CALL pragma_database_size();
+---------------+---------------+------------+--------------+-------------+-------------+----------+--------------+--------------+
| database_name | database_size | block_size | total_blocks | used_blocks | free_blocks | wal_size | memory_usage | memory_limit |
+---------------+---------------+------------+--------------+-------------+-------------+----------+--------------+--------------+
| file          | 512.0 KiB   | 262144   | 2            | 2         | 0         | 0 bytes| 256.0 KiB    | 25.0 GiB   |
+---------------+---------------+------------+--------------+-------------+-------------+----------+--------------+--------------+查看表信息


[*]查看所有表信息
-- 所有表信息
D PRAGMA show_tables;
+------+
| name |
+------+
| t1   |
| t2   |
| test |
+------+

[*]查看表详细信息
-- 表详细信息
D PRAGMA show_tables_expanded;
+----------+--------+------+--------------+--------------------+-----------+
| database | schema | name | column_names |    column_types    | temporary |
+----------+--------+------+--------------+--------------------+-----------+
| file   | main   | t1   |        | | false   |
| file   | main   | t2   |        | | false   |
| file   | main   | test |           |           | false   |
+----------+--------+------+--------------+--------------------+-----------+

[*]表结构
-- 表结构
D PRAGMA table_info('t1');
+-----+------+---------+---------+------------+-------+
| cid | name |type   | notnull | dflt_value |pk   |
+-----+------+---------+---------+------------+-------+
| 0   | a    | INTEGER | false   |            | false |
| 1   | b    | INTEGER | false   |            | false |
+-----+------+---------+---------+------------+-------+查看函数信息


[*]查看函数信息
-- 函数信息
D PRAGMA functions;
D PRAGMA functions;
┌────────────┬─────────┬────────────────────────┬─────────┬─────────────┬──────────────┐
│    name    │type   │       parameters       │ varargs │ return_type │ side_effects │
│varchar   │ varchar │       varchar[]      │ varchar │   varchar   │   boolean    │
├────────────┼─────────┼────────────────────────┼─────────┼─────────────┼──────────────┤
│ !__postfix │ SCALAR│             │         │ HUGEINT   │ false      │
│ !~~      │ SCALAR│    │         │ BOOLEAN   │ false      │
│ !~~*       │ SCALAR│    │         │ BOOLEAN   │ false      │
│ %          │ SCALAR│    │         │ SMALLINT    │ false      │
│ %          │ SCALAR│    │         │ UBIGINT   │ false      │
│ %          │ SCALAR│    │         │ UINTEGER    │ false      │版本与平台

-- 版本与平台
D PRAGMA version;
+-----------------+------------+
| library_version | source_id|
+-----------------+------------+
| v0.10.1         | 4a89d97db8 |
+-----------------+------------+

D PRAGMA platform;
+---------------+
|   platform    |
+---------------+
| windows_amd64 |
+---------------+其他(Profiling/Optimizer/StorageInfo)

-- Profiling
PRAGMA enable_profiling;
SET profiling_mode = 'detailed';
SET enable_profiling = 'query_tree';    logical query plan:
SET enable_profiling = 'query_tree_optimizer';    physical query plan:
PRAGMA disable_profiling;

-- Optimizer
PRAGMA disable_optimizer;
PRAGMA enable_optimizer;

-- Storage Info
D PRAGMA storage_info('t1');
+--------------+-------------+-----------+-------------+------------+--------------+-------+-------+--------------+------------------------------------------------------+-------------+------------+----------+--------------+--------------+
| row_group_id | column_name | column_id | column_path | segment_id | segment_type | start | count | compression|stats                                             | has_updates | persistent | block_id | block_offset | segment_info |
+--------------+-------------+-----------+-------------+------------+--------------+-------+-------+--------------+------------------------------------------------------+-------------+------------+----------+--------------+--------------+
| 0            | a         | 0         |          | 0          | INTEGER      | 0   | 3   | Uncompressed | | false       | true       | 1      | 0            |            |
| 0            | a         | 0         |       | 0          | VALIDITY   | 0   | 3   | Constant   |                | false       | true       | -1       | 0            |            |
| 0            | b         | 1         |          | 0          | INTEGER      | 0   | 3   | Uncompressed | | false       | true       | 1      | 16         |            |
| 0            | b         | 1         |       | 0          | VALIDITY   | 0   | 3   | Constant   |                | false       | true       | -1       | 0            |            |
+--------------+-------------+-----------+-------------+------------+--------------+-------+-------+--------------+------------------------------------------------------+-------------+------------+----------+--------------+--------------+性能调优


[*]DuckDB 性能调优主要涉及到参数、执行计划等。
尤其是观察 filter 和 projections 下推。
这里简单说明下使用 Explain 命令查看执行计划
查看执行计划

-- 查看执行计划
D explain select deptno,count(*) from big_emp group by deptno;

┌─────────────────────────────┐
│┌───────────────────────────┐│
││       Physical Plan                           ││
│└───────────────────────────┘│
└─────────────────────────────┘
┌───────────────────────────┐
│         PROJECTION                            │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─               │
│__internal_decompress_integ                           │
│   ral_integer(#0, 1)                           │
│             #1                            │
└─────────────┬─────────────┘
┌─────────────┴─────────────┐
│   PERFECT_HASH_GROUP_BY                            │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─               │
│             #0                            │
│      count_star()                           │
└─────────────┬─────────────┘
┌─────────────┴─────────────┐
│         PROJECTION                            │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─               │
│         deptno                            │
└─────────────┬─────────────┘
┌─────────────┴─────────────┐
│         PROJECTION                            │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─               │
│__internal_compress_integra                           │
│   l_usmallint(#0, 1)                           │
└─────────────┬─────────────┘
┌─────────────┴─────────────┐
│         SEQ_SCAN                           │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─               │
│          big_emp                            │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─               │
│         deptno                            │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─               │
│      EC: 1000000                            │
└───────────────────────────┘


-- 关闭优化器后,再观察看下
D PRAGMA disable_optimizer;
D explain select deptno,count(*) from big_emp group by deptno;

┌─────────────────────────────┐
│┌───────────────────────────┐│
││       Physical Plan                            ││
│└───────────────────────────┘│
└─────────────────────────────┘
┌───────────────────────────┐
│       HASH_GROUP_BY                            │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─               │
│             #0                            │
│      count_star()                           │
└─────────────┬─────────────┘
┌─────────────┴─────────────┐
│         PROJECTION                            │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─               │
│         deptno                            │
└─────────────┬─────────────┘
┌─────────────┴─────────────┐
│         SEQ_SCAN                           │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─               │
│          big_emp                            │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─               │
│   ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─               │
│      EC: 1000000                            │
└───────────────────────────┘密钥管理


[*]推荐文献


[*]密钥管理 - DuckDB


[*]支持管理的密钥类型
密钥类型服务 / 协议扩展azureAzure Blob 存储azureducklakeDuckLakeducklakegcsGoogle Cloud StoragehttpfshttpHTTP 和 HTTPShttpfshuggingfaceHugging FacehttpfsmysqlMySQLmysqlpostgresPostgreSQLpostgresr2Cloudflare R2httpfss3AWS S3httpfs插件管理

别名:扩展管理


[*]推荐文献


[*]插件管理 - DuckDB
查看插件


[*]获取扩展列表,请使用 duckdb_extensions 函数
SELECT
        extension_name, installed, description
FROM duckdb_extensions();扩展名称已安装描述arrow否Apache Arrow 和 DuckDB 之间的零拷贝数据集成autocomplete否在 Shell 中添加自动补全支持………此列表将显示哪些扩展可用、哪些扩展已安装、版本以及安装位置等信息。
此列表包含大多数(但并非所有)可用的核心扩展。有关完整列表,请参阅我们维护的核心扩展列表。

内置扩展


[*]DuckDB 的二进制分发版标准包含一些内置扩展。它们静态链接到二进制文件中,可以直接使用。
例如,要使用内置的 json 扩展来读取 JSON 文件
SELECT * FROM 'test.json';

[*]为了使 DuckDB 分发包轻量化,只有少数必需的扩展是内置的,具体取决于不同的分发版本。
哪个扩展在哪个平台上是内置的,已在核心扩展列表中说明。

安装更多扩展


[*]可以通过SQL命令安装DuckDB的扩展插件,这类插件程序一般只需要运行一次。
[*]要使非内置扩展在 DuckDB 中可用,需要执行两个步骤


[*]扩展安装是下载扩展二进制文件并验证其元数据的过程。
在安装过程中,DuckDB 会将下载的扩展和一些元数据存储在本地目录中。DuckDB 随后可以从该目录中按需加载扩展。这意味着安装只需进行一次。


[*]扩展加载是将二进制文件动态加载到 DuckDB 实例中的过程。
DuckDB 会在本地扩展目录中搜索已安装的扩展,然后加载它以使其功能可用。这意味着每次重新启动 DuckDB 时,所有已使用的扩展都需要(重新)加载。


[*]使 DuckDB 执行可安装扩展的安装和加载步骤有两种主要方法:显式方式和通过自动加载。
显式 INSTALL 和 LOAD


[*]在 DuckDB 中,扩展也可以显式安装和加载。非自动加载和可自动加载的扩展都可以通过这种方式安装。要显式安装和加载扩展,DuckDB 提供了专用的 SQL 语句 LOAD 和 INSTALL。例如,要安装和加载 spatial 扩展,请运行
INSTALL spatial;
LOAD spatial;使用这些语句,DuckDB 将确保 spatial 扩展已安装(如果已安装则忽略 INSTALL 语句),然后继续 LOAD spatial 扩展(如果已加载则再次忽略该语句)。
扩展存储库


[*]可以选定要安装扩展的存储库,方法是将 FROM repository 附加到 INSTALL / FORCE INSTALL 命令。此存储库可以是别名,例如 community,也可以是作为单引号字符串提供的直接 URL。
[*]安装/加载扩展后,可以使用 duckdb_extensions 函数获取更多信息。
自动加载扩展


[*]对于许多 DuckDB 的核心扩展,不需要显式加载和安装。DuckDB 包含一个自动加载机制,可以在核心扩展在查询中使用时立即安装和加载它们。例如,当运行
SELECT
    *
FROM 'https://raw.githubusercontent.com/duckdb/duckdb-web/main/data/weather.csv';

[*]DuckDB 将自动安装并加载 httpfs 扩展。无需显式的 INSTALL 或 LOAD 语句。
[*]并非所有扩展都可以自动加载。
这可能有多种原因:一些扩展会对正在运行的 DuckDB 实例进行多项更改,使得自动加载在技术上尚不可能。对于其他扩展,由于它们修改 DuckDB 行为的方式,更倾向于用户在使用前显式选择加入该扩展。
要查看哪些扩展可以自动加载,请查看核心扩展列表。
社区扩展


[*]DuckDB 支持安装第三方社区扩展。


[*]例如,您可以通过以下方式安装 avro 社区扩展:
INSTALL avro FROM community;

[*]社区扩展由社区成员贡献,但它们在集中式存储库中构建、签名和分发。
更新扩展


[*]内置扩展由于其内置于 DuckDB 二进制文件的性质而与 DuckDB 版本绑定,而可安装的扩展可以且确实会接收更新。为确保所有当前安装的扩展都处于最新版本,请调用
UPDATE EXTENSIONS;

[*]有关扩展版本的更多详细信息,请参阅扩展版本控制页面。
开发扩展


[*]核心扩展使用的相同 API 也可用于开发扩展。这允许用户扩展 DuckDB 的功能,使其最适合其领域。用于创建扩展的模板可在 extension-template 存储库中找到。此模板还包含有关如何开始构建自己的扩展的一些文档。
使用扩展


[*]请参阅安装说明和高级安装方法页面。
Z FAQ for DuckDB

Q: DBeaver 连接 DuckDB


[*]数据库 - 新建数据库连接- DuckDB - 下一步

[*]路径(输入: :memory:) - 下一步
当然,也可输入持久化的duckdb数据库文件路径。



[*]下载 duckdb 驱动包

即安装完成:


[*]尝试使用
select version();
-- v1.4.3

select * from read_csv("D:\Program-Data\DuckDB\datasources\tb_student.csv")
tb_student.csv
id,name,birthdate,comment
1,jack,2005-07-01,""
2,jane,2004-09-28,""Q: 使用 DuckLake 和 DuckDB 构建轻量级的 S3 数据湖?

此方案,未亲测。


[*]推荐文献


[*]使用 DuckLake 和 DuckDB 构建 S3 数据湖实战指南 - CSDN
由 DuckDB 和 DuckLake 组成的轻量级数据湖方案,旨在解决传统数据湖(如Hadoop+Hive)元数据管理复杂、查询性能低及厂商锁定等问题。
该方案为中小规模数据湖场景提供了简单、高性能且无厂商锁定的替代选择。
什么是 DuckLake 和 DuckDB?


[*]在现代数据架构中,数据湖(Data Lake) 和 湖仓一体(Lakehouse) 已成为存储和管理大规模结构化与非结构化数据的核心方案。然而,传统的数据湖(如 Hadoop + Hive)往往存在元数据管理复杂、查询性能低、依赖特定厂商等问题。
[*]DuckDB 是一个高性能的嵌入式分析数据库,支持 SQL 查询和向量化执行,特别适合本地和云环境下的数据分析。而 DuckLake 是一个基于 DuckDB 的轻量级表格式,它将元数据存储在 SQL 数据库(如 DuckDB)中,而实际数据则存储在开放格式(如 Parquet)的云存储(如 S3、GCS、Azure Blob Storage)上。
[*]DuckLake 的核心优势:


[*]✅ ​​简单易用​​:所有元数据管理通过 SQL 完成,无需复杂配置。
[*]✅ ​​高性能​​:元数据操作极快,查询性能优异。
[*]✅ ​​开放标准​​:数据存储在 Parquet 格式,元数据可移植。
[*]✅ ​​ACID 事务支持​​:支持 schema 演进、时间旅行(Time Travel)等高级功能。
环境准备:安装 DuckDB 并加载扩展


[*]确保已安装 DuckDB(官方下载地址)。然后,在 DuckDB 中加载必要的扩展以支持云存储和 DuckLake:
-- 安装并加载 AWS S3 支持
INSTALL aws;
LOAD aws;

-- 安装 HTTP 文件系统支持(可选,用于远程数据访问)
INSTALL httpfs;
LOAD httpfs;

-- 安装 Parquet 支持(用于读取/写入 Parquet 文件)
INSTALL parquet;
LOAD parquet;

-- 安装 DuckLake 扩展
INSTALL ducklake;
LOAD ducklake;

[*]配置 AWS 凭证
DuckDB 支持从环境变量或直接加载 AWS 凭证。推荐使用环境变量方式(更安全):
# 在终端设置 AWS 凭证(Linux/macOS)
export AWS_ACCESS_KEY_ID="your-access-key"
export AWS_SECRET_ACCESS_KEY="your-secret-key"
export AWS_REGION="us-east-1"# 替换为你的 S3 区域或者在 DuckDB 中直接加载凭证:
-- 直接加载 AWS 凭证(不推荐生产环境使用)
CALL load_aws_credentials();创建 DuckLake 目录并连接 S3


[*]DuckLake 使用 目录(Catalog) 管理表元数据。
我们可以在 S3 上创建一个 DuckLake 目录:
-- 在 S3 上创建 DuckLake 目录
ATTACH 'ducklake:metadata.ducklake' (
DATA_PATH 's3://your-bucket/your-prefix/'-- 替换为你的 S3 路径
);

[*]metadata.ducklake 是元数据文件名(DuckDB 会自动管理)。
[*]DATA_PATH 指定 S3 存储路径,所有 Parquet 数据将存储在此目录下。
创建表、插入数据、更新和删除

(1) 创建表

-- 在 DuckLake 目录中创建表
CREATE TABLE IF NOT EXISTS metadata.customers (
    customer_id INTEGER,
    first_name STRING,
    last_name STRING,
    email STRING,
    city STRING,
    created_at TIMESTAMP
);(2) 插入数据

-- 插入示例数据
INSERT INTO metadata.customers VALUES
(1, 'Alice', 'Smith', 'alice@example.com', 'New York', CURRENT_TIMESTAMP),
(2, 'Bob', 'Johnson', 'bob@example.com', 'San Francisco', CURRENT_TIMESTAMP);(3) 更新数据

-- 更新 Bob 的城市
UPDATE metadata.customers
SET city = 'Los Angeles'
WHERE customer_id = 2;(4) 删除数据

-- 删除 Alice 的记录
DELETE FROM metadata.customers WHERE customer_id = 1;(5) 查询数据

-- 查询所有客户
SELECT * FROM metadata.customers;高级功能:ACID 事务 & 时间旅行


[*]DuckLake 支持 ACID 事务,确保数据一致性。例如:
-- 开启事务
BEGIN TRANSACTION;

-- 插入新数据
INSERT INTO metadata.customers VALUES
(3, 'Charlie', 'Brown', 'charlie@example.com', 'Chicago', CURRENT_TIMESTAMP);

-- 更新数据
UPDATE metadata.customers
SET city = 'Seattle'
WHERE customer_id = 2;

-- 提交事务
COMMIT;

[*]时间旅行(Time Travel) 允许查询历史数据版本:
-- 查询 1 小时前的数据(假设 DuckLake 支持时间旅行)
SELECT * FROM metadata.customers AT TIMESTAMP '2025-05-28 12:00:00';注意:时间旅行功能可能需要额外配置,具体取决于 DuckLake 版本。
小结:为什么选择 DuckLake + DuckDB?

特性DuckLake + DuckDB传统数据湖 (Hive/Hadoop)元数据管理SQL 管理,简单高效依赖 Hive Metastore, 复杂查询性能向量执行,极快依赖 MapReduce/Spark, 较慢数据格式Parquet(开放标准)Parquet/ORC(但依赖特定工具)ACID 支持完整支持部分支持(如 Delta Lake)厂商锁定无锁定,纯开源可能依赖 Hadoop/Spark 生态

[*]DuckLake + DuckDB 提供了一种 轻量级、高性能、开源 的数据湖解决方案,特别适合:


[*]本地开发(嵌入式 DuckDB)
[*]云原生分析(S3/GCS 存储)
[*]需要 ACID 事务的场景
Y 推荐文献


[*]DuckDB


[*]安装包 https://duckdb.org/install/
[*]Guide https://duckdb.org/docs/stable/guides/overview
[*]SQL 介绍 https://duckdb.org/docs/stable/sql/introduction
[*]Github https://github.com/duckdb/duckdb


[*]Apache Parquet


[*][文件格式/数据存储] Apache Parquet:开源、高效的列式存储文件格式协议 - 博客园/千千寰宇
CASE : DuckDB 数据库 On Parquet
CASE : 二维数组保存为 parquet


[*]Apache Doris


[*]Aliyun OSS - Doris


[*]其他文献


[*]别再被“大数据”忽悠了:DuckDB,一场属于单机的复仇 - Weixin 2025.12
[*]数据Infra:基于 DuckDB 设计的分布式数据平台 - Weixin/DuckNest
注:这是一次思想实验,是与 DuckLake 数据仓库相反的创新路径


[*]【R数据库】duckdb/duckplyr包:整洁操作数据库 - Weixin
X 参考文献


[*]1 分钟安装 DuckDB - 腾讯云 2024.11.21
[*]嵌入式分析型数据库DuckDB - Zhihu 2025.1.27
[*]DuckDB 读写远程s3, oss, http Parquet 文件 - modb.pro 2024.1.25
    本文作者:      千千寰宇   
    本文链接:         https://www.cnblogs.com/johnnyzen   
    关于博文:评论和私信会在第一时间回复,或直接私信我。   
    版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA   许可协议。转载请注明出处!
    日常交流:大数据与软件开发-QQ交流群: 774386015      【入群二维码】参见左下角。您的支持、鼓励是博主技术写作的重要动力!   

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

诞楮 发表于 2026-1-7 22:38:10

用心讨论,共获提升!

狙兕 发表于 2026-1-14 13:44:03

收藏一下   不知道什么时候能用到

寂傧 发表于 2026-1-17 12:13:25

这个有用。

指陡 发表于 2026-1-18 03:15:15

鼓励转贴优秀软件安全工具和文档!

艋佰傧 发表于 2026-1-19 23:57:19

谢谢楼主提供!

叟减 发表于 2026-1-25 09:15:19

东西不错很实用谢谢分享

赖秀竹 发表于 2026-1-30 03:19:40

谢谢分享,辛苦了

觞刈 发表于 2026-2-2 04:11:03

感谢分享,学习下。

姬宜欣 发表于 2026-2-2 04:36:49

很好很强大我过来先占个楼 待编辑

辉伫 发表于 2026-2-2 22:26:59

东西不错很实用谢谢分享

醋辛 发表于 2026-2-3 07:36:55

分享、互助 让互联网精神温暖你我

柴古香 发表于 2026-2-3 10:42:48

谢谢楼主提供!

任静柔 发表于 2026-2-4 01:45:37

新版吗?好像是停更了吧。

祺簇 发表于 2026-2-5 06:14:47

前排留名,哈哈哈

咫噎 发表于 2026-2-5 07:42:33

过来提前占个楼

狙兕 发表于 2026-2-7 03:12:48

感谢分享,学习下。

咸和璧 发表于 2026-2-7 09:12:50

谢谢楼主提供!

叟澡帅 发表于 2026-2-8 02:42:11

感谢分享,学习下。

丝甲坞 发表于 2026-2-9 18:17:42

懂技术并乐意极积无私分享的人越来越少。珍惜
页: [1] 2
查看完整版本: [OLAP] DuckDB : 开源免费的、面向嵌入式场景、列式存储的分析型数据库