利用DeepSeek解决kdb+x进行tpch测试的几个问题及使用感受

上文其实没有成功运行tpch的22个标准查询中的任何一个,因为DeepSeek原始给出的导入语句有错,有一些表没有导入。

1.解决类型及长度问题导致的插入tbl文件到内存表失败。
kdb+x的Reference card()提到的基本数据类型如下:

Basic datatypes
n   c   name      sz  literal            null inf SQL       Java      .Net
------------------------------------------------------------------------------------
0   *   list
1   b   boolean   1   0b                                    Boolean   boolean
2   g   guid      16                     0Ng                UUID      GUID
4   x   byte      1   0x00                                  Byte      byte
5   h   short     2   0h                 0Nh  0Wh smallint  Short     int16
6   i   int       4   0i                 0Ni  0Wi int       Integer   int32
7   j   long      8   0j                 0Nj  0Wj bigint    Long      int640                  0N   0W
8   e   real      4   0e                 0Ne  0We real      Float     single
9   f   float     8   0.0                0n   0w  float     Double    double0f                 0Nf
10  c   char      1   " "                " "                Character char
11  s   symbol        `                  `        varchar
12  p   timestamp 8   dateDtimespan      0Np  0Wp           Timestamp DateTime (RW)
13  m   month     4   2000.01m           0Nm
14  d   date      4   2000.01.01         0Nd  0Wd date      Date
15  z   datetime  8   dateTtime          0Nz  0wz timestamp Timestamp DateTime (RO)
16  n   timespan  8   00:00:00.000000000 0Nn  0Wn           Timespan  TimeSpan
17  u   minute    4   00:00              0Nu  0Wu
18  v   second    4   00:00:00           0Nv  0Wv
19  t   time      4   00:00:00.000       0Nt  0Wt time      Time      TimeSpanColumns:
n    short int returned by type and used for Cast, e.g. 9h$3
c    character used lower-case for Cast and upper-case for Tok and Load CSV
sz   size in bytes
inf  infinity (no math on temporal types); 0Wh is 32767hRO: read only; RW: read-write

tpch数据库常用的也就整型、浮点、日期、字符、变长字符串这几种,在导入时指定的类型要与数据文件中的数据匹配,就没有问题。
导入同时建表的语法是:

表名:字段列表(用反引号前缀表示变长字符串,无需分隔符),xcol("大写的各列数据类型列表"; enlist "数据文件的列分隔符" ) 0: 反引号冒号开头的文件路径

比如orders表, 它的SQL建表语句如下:

CREATE TABLE ORDERS  ( 
O_ORDERKEY       INTEGER ,
O_CUSTKEY        INTEGER ,
O_ORDERSTATUS    CHAR(1) ,
O_TOTALPRICE     DECIMAL(15,2) ,
O_ORDERDATE      DATE ,
O_ORDERPRIORITY  CHAR(15) ,  
O_CLERK          CHAR(15) , 
O_SHIPPRIORITY   INTEGER ,
O_COMMENT        VARCHAR(79) );

对应导入语句就是

\t orders:`o_orderkey`o_custkey`o_orderstatus`o_totalprice`o_orderdate`o_orderpriority`o_clerk`o_shippriority`o_comment xcol ("IISFDSSIS"; enlist "|") 0: `:/mnt/c/d/tpch/orders.tbl;

同理,lineitem表导入语句就是

\t lineitem:`l_orderkey`l_partkey`l_suppkey`l_linenumber`l_quantity`l_extendedprice`l_discount`l_tax`l_returnflag`l_linestatus`l_shipdate`l_commitdate`l_receiptdate`l_shipinstruct`l_shipmode`l_comment xcol ("IIIIFFFFCCDDDSSS"; enlist "|") 0: `:/mnt/c/d/tpch/lineitem.tbl;

整数类型有3种,j表示64位,i表示32位,h表示16位二进制。浮点有两种,e表示单精度、f表示双精度。

2.解决将内存表保存到持久存储的数据库的嵌套目录问题
前文提到

1. 创建数据库目录
// 创建数据库目录(如果不存在)
system "mkdir -p tpch_db";2. 保存表到磁盘
// 保存 region 表
`:tpch_db/region/ set .Q.en[`:tpch_db] region;
输入//
退出kdb
3. 下次启动时加载
// 启动 kdb+ 并加载数据库
q tpch_db

但是,此时如果继续用上述命令保存其他表,就会产生数据库的嵌套目录问题,具体表现是在tpch_db目录下又建立了tpch_db目录,其他表被保存到更深的目录中,并且退出重新进入kdb, 用tables[]命令看不到后加的表。
DeepSeek给出的方法不完全对。他说要

// 更新 .d 文件(包含所有表名)
(`:tpch_db/.d) set `customer`part`nation;

但其实,只要在操作系统把深层目录移动到父目录就可以识别了。
关键是要修改保存表的路径,不能再包含tpch_db,比如导入supplier, 这么写

\t `:supplier/ set .Q.en[`:tpch_db] supplier;

就能使supplier保存在当前数据库,也就是首层tpch_db目录下。

3.部分解决存储分区表问题

上文提到,导入单个大表非常慢,希望分区可以解决,但是DeepSeek给出的原始导入分区语句有误,报错如下

\t {date: first x`o_orderdate; `:orders/,string date/ set .Q.en[`:tpch_db] x; } each {select from ordersByDate where o_orderdate=x} each distinct ordersByDate`o_orderdate;
'[0]  \t {date: first x`o_orderdate; `:orders/,string date/ set .Q.en[`:tpch_db] x; } each {select from ordersByDate where o_orderdate=x} each distinct ordersByDate`o_orderdate;^

把报错位置提供给DeepSeek后,他给出了正确的语句

\t {date: first x`o_orderdate; path: `$":orders/",string date; path set .Q.en[`:tpch_db] x;} each {select from ordersByDate where o_orderdate=x} each distinct ordersByDate`o_orderdate;

语法虽然对了,可以执行,但速度很慢,orders 2分钟才生成了200多个256K的小文件,64MB,原始数据有1.7GB,怎么加速?DeepSeek给出了多个方法

要加速 kdb+/q 中将大容量 orders 表按日期分区存储到磁盘的过程,可以综合采用以下优化策略。您的原始数据 1.7GB 生成过多小文件(200+个 256KB)导致 I/O 瓶颈,以下是针对性解决方案:


1. 并行化处理(核心优化)

使用 peach 多线程并行写入,需先设置从线程数:

// 启动 q 时启用 4 个从线程(根据 CPU 核心数调整)
q -s 4// 在脚本中并行分区保存
{[date]data: select from ordersByDate where o_orderdate=date;path: `$":tpch_db/orders/",string date;path set .Q.en[`:tpch_db] data;} peach distinct ordersByDate`o_orderdate;

效果:写入速度可提升 3-5 倍(取决于磁盘 I/O 并行能力)。


2. 批量写入(减少小文件)

合并相邻日期的数据,减少文件数量:

// 按月份分组写入(替代按天)
months: `month$distinct ordersByDate`o_orderdate;
{[m]dates: where `month$ordersByDate`o_orderdate=m;path: `$":tpch_db/orders/",string m;path set .Q.en[`:tpch_db] select from ordersByDate where `month$o_orderdate=m;} each months;

优势:1.7GB 数据可能从 200+ 文件减少到 20-30 个月份文件,显著降低 I/O 压力。


3. 启用压缩(减少磁盘写入量)

// 设置高压缩比(压缩级别 17,块大小 128KB)
.z.zd:17 2 7;  // 格式:[compressionLevel; log2BlockSize; algorithm]// 压缩后再写入
path set .Q.en[`:tpch_db] data;

效果:文本数据通常可压缩至原始大小的 30%,写入量从 1.7GB → ~500MB。


4. 直接原始数据分区(跳过内存排序)

orders.tbl 文件已按日期排序,直接流式处理避免全量加载内存:

// 按日期流式读取并分区保存
.Q.fs[{ [x]date: first x`o_orderdate;path: `$":tpch_db/orders/",string date;path set .Q.en[`:tpch_db] x;}] (`:orders.tbl; "JJFSDSSIS"; "|");  // 指定数据类型和分隔符

优势:内存占用极低,适合超大文件。


5. 文件系统优化

调整挂载参数(Linux)
# 挂载时启用写入缓存和更大IO队列
mount -o remount,noatime,discard,data=writeback /mnt/tpch_db
预分配文件空间
// 在 q 中预创建空文件(减少碎片)
{[date;sizeMB]path: `$":tpch_db/orders/",string date;h: hopen path;hclose h;system truncate -s ",(string sizeMB),"M ",1_string path;}[;256] each distinct ordersByDate`o_orderdate;  // 预分配256MB/文件

6. 完整优化脚本示例

// 初始化环境
system "mkdir -p tpch_db/orders";
.z.zd:17 2 7;  // 启用压缩
\l tpch_db     // 加载已有数据库// 方法1:并行按月分区(推荐)
months: distinct `month$ordersByDate`o_orderdate;
{[m]path: `$":tpch_db/orders/",string m;path set .Q.en[`:tpch_db] select from ordersByDate where `month$o_orderdate=m;} peach months;// 方法2:流式处理原始文件(替代方案)
.Q.fs[{ [x]m: `month$first x`o_orderdate;path: `$":tpch_db/orders/",string m;path upsert .Q.en[`:tpch_db] x;}] (`:orders.tbl; "JJFSDSSIS"; "|");

性能对比

方法耗时(1.7GB数据)文件数量内存占用
原始单线程按天~120秒200+
并行按月(4线程)~25秒12-24
流式处理~40秒自动合并极低

进一步建议

  1. 监控磁盘 I/O
    iostat -xmt 1  # 观察磁盘利用率
    
  2. 使用更快的存储
    • 临时写入到 SSD(如 /dev/shm),完成后移动到 HDD
  3. 后期维护
    .Q.gc[];  // 定期回收内存
    

通过组合 并行化 + 批量合并 + 压缩,您应该能将总写入时间从 2 分钟缩短到 20-30 秒。

经过试验,多个进程并行有效,partsupp.tbl有1.1GB,25秒完成导入,14秒写入数据库

q tpch_db -s 4
\t partsupp:`ps_partkey`ps_suppkey`ps_availqty`ps_supplycost`ps_comment xcol ("IIIFS"; enlist "|") 0: `:/mnt/c/d/tpch/partsupp.tbl;
24704
\t `:partsupp/ set .Q.en[`:tpch_db] partsupp;
13716

按月份分区的语法还是不对,放弃分区,存成单独文件,还挺快的。

\t {[m] monthData: select from ordersByDate where `month$o_orderdate = m; path: `$":orders/",string m; path set .Q.en[`:tpch_db] monthData;  } each months;
'type[10] {[m] monthData: select from ordersByDate where `month$o_orderdate = m; path: `$":orders/",string m; path set .Q.en[`:tpch_db] monthData;  }^
\t `:orders/ set .Q.en[`:tpch_db] orders;
14835

但并行也更占内存,原来单进程能导入的最大表,7.3GB的lineitem.tbl, 设为多进程,并行度4个或2个,都报错失败,也可能由于kdb已经加载了其他表,占用了很多内存。

\t lineitem:`l_orderkey`l_partkey`l_suppkey`l_linenumber`l_quantity`l_extendedprice`l_discount`l_tax`l_returnflag`l_linestatus`l_shipdate`l_commitdate`l_receiptdate`l_shipinstruct`l_shipmode`l_comment xcol ("IIIIFFFFCCDDDSSS"; enlist "|") 0: `:/mnt/c/d/tpch/lineitem.tbl;
rlwrap: error: read error on master pty: Input/output error

4.未能解决真实的tpch查询执行失败问题
虽然只导入了8张表,但有些tpch查询是用不到lineitem表的。其中Q3就是,将sql语句的换行全都删除,然后执行,结果还是被杀进程了。

s)SELECT s_acctbal,s_name,n_name,p_partkey,p_mfgr,s_address,s_phone,s_comment FROM part,supplier,partsupp,nation,region WHERE p_partkey = ps_partkey AND s_suppkey = ps_suppkey AND p_size = 15 AND p_type LIKE '%BRASS' AND s_nationkey = n_nationkey AND n_regionkey = r_regionkey AND r_name = 'EUROPE' AND ps_supplycost = ( SELECT min(ps_supplycost) FROM partsupp,supplier,nation,region WHERE p_partkey = ps_partkey AND s_suppkey = ps_suppkey AND s_nationkey = n_nationkey AND n_regionkey = r_regionkey AND r_name = 'EUROPE') ORDER BY s_acctbal DESC,n_name,s_name,p_partkey LIMIT 10
Killed

而同样的机器duckdb执行sf=10的q3只要1.5秒,看来kdb对tpch测试不擅长,它的主要优势还是时间序列分析。而且学习曲线陡峭,若没有AI辅助,自己查询文档资料,连这些都很难短时间做到。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/92959.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/92959.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SGLang 核心技术详解

SGLang 作为一个高性能的 LLM 服务框架,通过一系列先进的优化技术实现了卓越的推理性能。下面详细解释其核心功能组件: 1. RadixAttention 用于前缀缓存 核心概念 RadixAttention 是 SGLang 独创的前缀缓存机制,基于 Radix Tree(基…

精密全波整流电路(四)

精密全波整流电路(四) 背景说明 [[精密半波整流电路|半波整流]]虽然能实现交直流信号的转换,但是半波整流只能保留信号半个周期的能量,导致信号能量的利用率不高。 因此,在一些场合需要使用到全波整流电路。 同样的&…

深入解读Prometheus 2.33 Series Chunks压缩特性:原理与实践

深入解读Prometheus 2.33 Series Chunks压缩特性:原理与实践 随着监控指标规模不断增长,Prometheus的本地TSDB存储压力日益增大。为提升存储效率,Prometheus 2.33引入了Series Chunks压缩特性,对时间序列数据在写入和存储时进行深…

SpringBoot整合Liquibase提升数据库变更的可控性、安全性、自动化程度(最详细)

为什么要使用liquibase?- 团队协作与版本管理- 当多人(或多个小组)并行开发、对同一数据库结构进行变更时,如果仅靠手写 SQL 脚本,很 容易产生冲突或漏掉某些变更。- Liquibase 将所有 DDL/DML 操作以“changeset”形式纳入源码管…

数据写入因为汉字引发的异常

spark 数据写hive表,发生 查询分区异常问题 异常: 25107124 19 26.49 ERROR Hive: MelaException(message.Exception thrown when execuling quey. S ELECT DISTINCT ‘org apache.hadop.hive melastore .modelMpartion As"NUCLEUS TYPE,AONCREATE TIME,AO.LAST ACCE…

Springboot项目实现将文件上传到阿里云

Springboot项目实现将文件上传到阿里云 一、概述二、具体步骤 2.1引入阿里云工具 首先先建utils包,然后引入AliOSSUtils类,如下: package com.hechixueyuan.forestfiredetectionsystem.utils;import com.aliyun.oss.OSS; import com.aliyun.o…

如何理解 TCP 是字节流协议?详解

文章目录一、面向字节流二、粘包问题应用层如何解决粘包问题?一、面向字节流 使用 TCP socket 进行网络编程,Linux 内核会给每个 socket 都分配一个发送缓冲区和一个接收缓冲区 由于缓冲区的存在, TCP 读写不需要一一匹配,例如:…

面试问题总结——关于OpenCV(二)

最近小组在面试视觉算法工程师,顺便整理了一波关于OpenCV的面试题目。 有些知识点也不深入,对于写的不对的地方,欢迎指正。 目录 20.像素梯度如何计算? 21.关于开运算和闭运算的理解 22.开运算和闭运算有什么优缺点? 23.图像插值有哪些? 24.图像金字塔的原理 25.边缘检测…

目标导向的强化学习:问题定义与 HER 算法详解—强化学习(19)

目录 1、目标导向的强化学习:问题定义 1.1、 核心要素与符号定义 1.2、 核心问题:稀疏奖励困境 1.3、 学习目标 2、HER(Hindsight Experience Replay)算法 2.1、 HER 的核心逻辑 2.2、 算法步骤(结合 DDPG 举例…

2025 XYD Summer Camp 7.21 智灵班分班考 · Day1

智灵班分班考 Day1 时间线 8:00 在滨兰实验的远古机房中的一个键盘手感爆炸的电脑上开考。开 T1,推了推发现可以 segment tree 优化 dp,由于按空格需要很大的力气导致马蜂被迫改变。后来忍不住了顶着疼痛按空格。8:30 过了样例,但是没有大样…

基于多种主题分析、关键词提取算法的设计与实现【TF-IDF算法、LDA、NMF分解、BERT主题模型】

文章目录有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主一、项目背景二、研究目标与意义三、数据获取与处理四、文本分析与主题建模方法1. 传统方法探索2. 主题模型比较与优化3. 深度语义建模与聚类五、研究成果与应用价值六、总结与展望总结每文一…

MDC(Mapped Diagnostic Context) 的核心介绍与使用教程

关于日志框架中 MDC(Mapped Diagnostic Context) 的核心介绍与使用教程,结合其在分布式系统中的实际应用场景,分模块说明: 一、MDC 简介 MDC(映射诊断上下文) 是 SLF4J/Logback 提供的一种线程…

Linux随记(二十一)

一、highgo切换leader,follow - 随记 【待写】二、highgo的etcd未授权访问 - 随记 【待写】三、highgo的etcd未授权访问 - 随记 【待写】3.2、etcd的metric未授权访问 - 随记 【待写】四、安装Elasticsearch 7.17.29 和 Elasticsearch 未授权访问【原理扫描】…

Java环境配置之各类组件下载安装教程整理(jdk、idea、git、maven、mysql、redis)

Java环境配置之各类组件下载安装教程整理(jdk、idea、git、maven、mysql、redis)1.[安装配置jdk8]2.[安装配置idea]3.[安装配置git]4.[安装配置maven]5.[安装配置postman]6.[安装配置redis和可视化工具]7.[安装配置mysql和可视化工具]8.[安装配置docker]…

配置https ssl证书生成

1.可用openssl生成私钥和自签名证书 安装opensslsudo yum install openssl -y 2.生成ssl证书 365天期限sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \-keyout /etc/ssl/private/nginx-selfsigned.key \-out /etc/ssl/certs/nginx-selfsigned.crt3、按照提示编…

编程语言Java——核心技术篇(四)集合类详解

言不信者行不果,行不敏者言多滞. 目录 4. 集合类 4.1 集合类概述 4.1.1 集合框架遵循原则 4.1.2 集合框架体系 4.2 核心接口和实现类解析 4.2.1 Collection 接口体系 4.2.1.1 Collection 接口核心定义 4.2.1.2 List接口详解 4.2.1.3 Set 接口详解 4.2.1.4…

GaussDB 数据库架构师(八) 等待事件(1)-概述

1、等待事件概述 等待事件:指当数据库会话(session)因资源竞争或依赖无法继续执行时,进入"等待"状态,此时产生的性能事件即等待事件。 2、等待事件本质 性能瓶颈的信号灯,反映CPU,I/O、锁、网络等关键资源的阻塞情况。…

五分钟系列-文本搜索工具grep

目录 1️⃣核心功能​​ ​​2️⃣基本语法​​ 3️⃣​​常用选项 & 功能详解​​ ​​4️⃣经典应用场景 & 示例​​ 5️⃣​​重要的提示 & 技巧​​ ​​6️⃣总结​​ grep 是 Linux/Unix 系统中功能强大的​​文本搜索工具​​,其名称源自 …

Java面试题及详细答案120道之(041-060)

《前后端面试题》专栏集合了前后端各个知识模块的面试题,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs&…

【尝试】本地部署openai-whisper,通过 http请求识别

安装whisper的教程,已在 https://blog.csdn.net/qq_23938507/article/details/149394418 和 https://blog.csdn.net/qq_23938507/article/details/149326290 中说明。 1、创建whisperDemo1.py from fastapi import FastAPI, UploadFile, File import whisper i…