DuckDB 配置与 PRAGMA 详解
详解 DuckDB 的两套配置体系:PRAGMA 语句(version/database_size/table_info)与 duckdb_settings 配置表(SET/RESET/current_setting)。涵盖 memory_limit、threads、temp_directory、access_mode、default_order 等常用参数默认值与实测效果,基于 DuckDB v1.5.6 实测。
DuckDB 配置与 PRAGMA 详解
目标:掌握 DuckDB 的两种配置入口——
PRAGMA语句(查询库/表结构信息)与duckdb_settings()配置表(通过SET/RESET/current_setting管理运行时参数)。DuckDB 是嵌入式分析型数据库,无守护进程,配置作用于每个进程内打开的库。本文所有默认值与设置效果基于 DuckDB v1.5.6 实测。
环境信息
| 信息项 | 值 |
|---|---|
| DuckDB 版本 | v1.5.6(Variegata) |
| 操作系统 | Ubuntu 22.04.5 LTS |
| 演示库 | 内存库 / /tmp/e.db |
一、DuckDB 配置体系概览
| 体系 | 语法 | 用途 |
|---|---|---|
| PRAGMA | PRAGMA xxx; | 查询运行信息 / 库结构 / 数据库大小 |
| 配置表 | SELECT * FROM duckdb_settings(); | 列出全部可调参数与当前值 |
| 设置 | SET name=value; | 修改运行时参数 |
| 读取 | current_setting('name') | 读当前参数值 |
| 重置 | RESET name; | 恢复默认 |
二、PRAGMA 详解
2.1 版本与校验信息
PRAGMA version;
实测输出(duckbox):
┌─────────────────┬────────────┬───────────┐
│ library_version │ source_id │ codename │
│ varchar │ varchar │ varchar │
├─────────────────┼────────────┼───────────┤
│ v1.5.6 │ 069cc9f9b5 │ Variegata │
└─────────────────┴────────────┴───────────┘
2.2 数据库大小与内存使用
PRAGMA database_size;
输出含 database_size、block_size(262144)、total_blocks/used_blocks/free_blocks、wal_size、memory_usage、memory_limit(当前配置内存上限)。实测小库显示 0 bytes、memory_usage 256.0 KiB、memory_limit 25.0 GiB。
2.3 查看表结构
SELECT * FROM pragma_table_info('emp');
实测输出:返回列 cid/name/type/notnull/dflt_value/pk,如 id INTEGER、name VARCHAR。
2.4 列出表
SHOW TABLES;
2.5 常用 PRAGMA 一览
| PRAGMA | 作用 |
|---|---|
version | 版本/源码 ID/代号 |
database_size | 库大小、块数、内存使用 |
pragma_table_info('t') | 表列定义 |
pragma_database_list | 库清单 |
pragma_function_list | 内建函数清单 |
三、duckdb_settings() 配置表
所有可调参数集中在一张视图里,结构如下:
DESCRIBE SELECT * FROM duckdb_settings();
| 字段 | 说明 |
|---|---|
name | 参数名 |
value | 当前值 |
description | 中文/英文说明 |
input_type | 取值类型(BIGINT/VARCHAR/BOOLEAN…) |
scope | 作用域(DuckDB 中多为 GLOBAL) |
四、常用参数详解(默认值实测)
查询常用参数当前值:
SELECT name, value, scope FROM duckdb_settings()
WHERE name IN ('threads','memory_limit','temp_directory',
'max_temp_directory_size','access_mode',
'default_order','default_null_order');
实测输出:
access_mode automatic
default_null_order NULLS_LAST
default_order ASCENDING
enable_external_access true
max_temp_directory_size 90% of available disk space
memory_limit 25.0 GiB
temp_directory .tmp
threads 6
4.1 memory_limit(内存上限)
默认 25.0 GiB。分析查询会用满此预算缓存中间结果:
SET memory_limit='2GB';
SELECT current_setting('memory_limit'); -- 1.8 GiB(2GB 的二进制换算)
RESET memory_limit;
SELECT current_setting('memory_limit'); -- 25.0 GiB
4.2 threads(线程数)
默认等于机器逻辑核数(实测 6)。OLAP 查询可利用多核并行:
SET threads=4;
SELECT current_setting('threads'); -- 4
4.3 temp_directory 与 max_temp_directory_size
中间结果溢出到磁盘的目录(默认 .tmp)与其大小上限(默认 90% 可用盘)。
4.4 其它
access_mode=automatic:只读/读写自动。default_order=ASCENDING、default_null_order=NULLS_LAST:无ORDER BY时默认排序。enable_external_access=true:允许读外部文件(read_csv等)。
五、SET / RESET 使用要点
- 语法:
SET name=value;、RESET name;、current_setting('name')。 - 作用域:DuckDB 配置项 scope 基本为
GLOBAL;实测SET LOCAL memory_limit=...会报Not implemented Error,不支持会话局部设置。 - 取值宽松:
memory_limit接受字符串'2GB',线程数接受整数。
完整设置示例:
SET memory_limit='4GB';
SET threads=8;
SET temp_directory='/tmp/ddb';
SELECT current_setting('memory_limit'), current_setting('threads');
RESET memory_limit; RESET threads; RESET temp_directory;
六、常见问题(FAQ)
1. memory_limit 设 2GB 怎么显示 1.8 GiB?
DuckDB 用二进制 GiB(1 GiB=1024³ 字节)显示:2,000,000,000 字节 ≈ 1.8 GiB。无需处理,属显示口径。
2. SET LOCAL 报 "not implemented"?
DuckDB 当前未实现会话级局部配置,配置项作用域为 GLOBAL。直接 SET 即可。
3. 提升大查询性能怎么配?
SET threads=<核数>;
SET memory_limit=0.8*RAMGiB; -- 按实际内存
SET enable_external_access=true;
4. 想知道有哪些可用配置?
SELECT name, value, description FROM duckdb_settings() ORDER BY name;
七、小结
DuckDB 配置集中、无守护进程:PRAGMA 查版本/库信息/表结构,duckdb_settings() 列出全部可调项,SET/RESET/current_setting 动态管理 memory_limit、threads、temp_directory 等。配合《DuckDB 命令行与 SQL 工具详解》上手分析与《DuckDB 备份与数据导入导出》做数据迁移。