ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

金仓KES向量数据库实战:一条SQL干掉ETL,机器人不再把停产货当现货卖

2026/8/25 13:09:01 拓冰建站 浏览量
金仓KES向量数据库实战:一条SQL干掉ETL,机器人不再把停产货当现货卖 一、背景一套跑了一年的三件套1.1 先说项目我在一家制造企业做平台开发。去年接了个活儿给内部客服和售后搭智能问答说穿了就是 RAG。把几十年的产品手册、维修案例、工单记录喂给大模型一线员工提问的时候系统把最相关的资料片段捞出来递给模型模型再组织成人话回答。去年上的线。用的人不少日均几千次提问吧。别看我现在说得轻巧当年的架构可是照着行业标配抄的三件套。MySQL 存业务元数据和文档目录一个专用向量数据库存 embedding中间靠 ETL 任务搬砖。就这套东西跑了一年。1.2 当时是怎么切的分工大概这样。文档正文和切片进 MySQL运营同事要审核管理嘛。切片算出来的 embedding 灌进向量库建 ANN 索引管相似度检索。至于权限、产品线、有效性这些业务属性两边都存了一份向量库里放元数据字段用来过滤MySQL 里那份当权威版本。算法组的小林当时就嘀咕过说两边都存早晚要出事。我还挺不耐烦回他说 ETL 十分钟跑一次呢能出啥事。嗯。这个 Flag 立得相当标准。二、出事了机器人把停产货当现货卖2.1 周二下午售后群炸了。机器人信誓旦旦地告诉客户某款停产大半年的控制器目前有货可以下单。客服没多想照着回了。客户还真去下了单。我到现在都记得排查的过程。顺着问题向量去检索命中的确实是那款产品的资料相似度还挺高检索这步没毛病。回头查元数据MySQL 里这条产品三个月前就标记停售了。卡在哪儿ETL。某次向量库升级之后同步任务的鉴权配置失效了。注意啊任务没报错它就是安静地不干活了。停售标记从头到尾没走到向量库的过滤字段里。更头皮发麻的是这种安静失败不是头一回。上一次是权限字段某部门的文档下线了向量库里的副本还活得好好的测试同学闲逛才发现的。两次一个根儿。同一份业务事实存两个系统靠异步任务保持一致那延迟和漂移就不是会不会发生的问题了只是什么时候被人撞见的问题。2.2 复盘会上算的账复盘会开完我没走一个人把这一年的账摊开来算了算。同步链路四道工序解析、切片、向量化、搬运哪道都可能卡住监控只盖得住两道。混合查询也别扭用户的真实问题从来不是纯相似度是某产品线、我有权限、还没过期的资料里搜这么一串。向量库的元数据过滤又弱只能应用层先查 MySQL 拿 id再攥着 id 列表去向量库搜。权限范围一大列表好几千个性能当场趴窝。运维是双份的苦。两套库两套备份两套告警。老徐半夜被告警吵醒原话是我还得先想半分钟这次是谁家的。那天下班路上我一直在想小林那句话。三、换思路让向量长回数据库里3.1 一个朴素得要命的问题后来某次内部讨论小林又开口了。向量不就是表里的一列吗凭什么不能跟别的字段住一张表、进同一个事务会议室安静了几秒。这问题听着简单把我们整个架构的前提给问松了。顺着这个方向查资料最后落在金仓数据库 KES 的向量能力上。思路跟小林那个问题一模一样向量作为一种数据类型直接建在关系表里跟数值、文本、JSON、GIS、时序一块儿活在同一个库里。没有搬运这回事一条 SQL 里向量检索和普通条件一起下。坦白讲我起先犯嘀咕。专用向量库那边迭代得跟飞一样数据库内置的向量能力会不会是个玩具亲手测了两件事才踏实。一是人家自研实现了 HNSW 和 IVFFlat 两种近似索引还带 SIMD 指令级的加速不是扫个表糊弄事。二是向量数据直接吃数据库的 ACID 事务这个市面上不少 NoSQL 形态的向量库给不了而对我们这种元数据改了向量必须跟着变的场景恰恰是要命的那条。3.2 新架构长什么样改造完我盯着看了半天有点不习惯就这么简单原来元数据和向量分两个库、ETL 搬着砖、滞后还漂移现在一张表向量就是其中一列改完即生效。原来相似度和过滤分两步走、应用层拿针线缝合现在一条 SQL 混合检索全下推。原来备份监控权限配置什么都得来两份现在一份。老徐的原话是晚上能睡整觉了。四、动手改造4.1 建表文档切片表直接带上向量列。我们的 embedding 模型输出 768 维类型声明里就写 768别的不用多想CREATETABLEdoc_chunks(id BIGSERIALPRIMARYKEY,doc_idBIGINTNOTNULL,doc_titleTEXT,chunk_textTEXTNOTNULL,embedding VECTOR(768)NOTNULL,product_lineTEXT,is_activeBOOLEANDEFAULTTRUE,dept_permTEXT[],updated_at TIMESTAMPTZDEFAULTnow());多看一眼 is_active 和 dept_perm 这俩字段。停产标记、部门权限原来住在另一个库里现在跟向量睡同一行。产品停售了一条 UPDATE 把 is_active 置掉事务提交那一瞬间检索结果里就再也见不着它了。开头那个事故搁这个架构下压根没有发生的土壤。4.2 索引选型加两个血泪坑两种索引我们都实测了代码一起贴给你-- HNSW多层图结构召回高、查询快就是吃内存、建得慢CREATEINDEXidx_chunk_hnswONdoc_chunksUSINGhnsw(embedding vector_cosine_ops);-- IVFFlat先聚类再倒排省内存、建得快拿 probes 调精度CREATEINDEXidx_chunk_ivfONdoc_chunksUSINGivfflat(embedding vector_cosine_ops);最后定的 HNSW。语料百万级内存扛得住而客服场景对召回率敏感漏一条关键维修案例可比慢十毫秒严重多了。你要是向量上亿、内存又紧那 IVFFlat 值得先试。补一句这儿的索引在数据插入更新时是实时维护的不存在建完索引就不让改数据那种憋屈事。坑踩了俩。第一个IVFFlat 千万别在空表上建。它先对全量数据聚类再分桶空表建出来的分桶全是错的召回惨到没法看。我们当时还以为是版本 bug排了一晚上最后发现是自己用法不对。先灌数后建索引顺序别反。第二个更隐蔽。用余弦距离的话向量入库前要归一化不然模长会掺进距离里捣乱排序结果莫名其妙地不对。我们有一阵子检索质量忽好忽坏查了好几天才定位到这儿说起来都是泪。4.3 检索就一条 SQL改造后最爽的部分。用户提问的完整检索就这一条-- q_vec 是应用侧把用户问题向量化后传进来的参数SELECTdoc_title,chunk_text,embeddingq_vecASdistanceFROMdoc_chunksWHEREis_activeTRUEANDproduct_line工业控制器ANDdept_perm ARRAY[after_sales]ORDERBYembeddingq_vecLIMIT5;看看 WHERE 里混了些什么。有效性产品线数组权限判断再搭上 算的余弦距离排序。原来那个先查 id 列表再传给向量库的两段式整个被压进数据库一次执行。权限列表几千条也不虚了过滤条件下推扫描范围先砍一大截。我观察下来这是融合架构最被低估的地方。大家盯着向量检索性能比来比去很少有人算省掉的那条同步链路值多少钱。4.4 意外收获顺手的惊喜值得一小节。向量类型支持加减、数乘、拼接还带 AVG、SUM 这类聚合。我拿它算过全部语料向量的均值专门捞离群的切片-- 找跟语料中心离得最远的切片多半是切坏了的或者内容异常的WITHcenterAS(SELECTAVG(embedding)AScFROMdoc_chunks)SELECTid,doc_title,embeddingcASdistanceFROMdoc_chunks,centerORDERBYdistanceDESCLIMIT20;跑出来一瞧果然一堆切稀碎的表格和乱码 PDF。以前这种活儿得导出去写 Python 脚本现在 SQL 一条。五、跑了三个月的账说几个拿得出手的数。检索链路里彻底没有 ETL 这号角色了数据新鲜度从最多滞后十分钟变成事务级。混合检索的 P95 从 180ms 掉到 40ms 上下大头是省了两段式那个应用层往返。运维对象两套变一套老徐的告警群肉眼可见地清净了。至于停产产品当现货卖这类事故架构上没有它发生的土壤了。代价也得老实交代。单一库资源共享高峰期向量检索和普通业务查询会抢 CPU。我们靠资源隔离配置压了压不算完美但跟伺候同步链路比省心太多。六、写在最后这回改造给我最大的触动是AI 应用的架构难题好多时候不在模型身上在数据怎么组织。向量数据库这个词听着像要开新世界扒开看向量就是一种数据形态嘛它在关系库里完全能活得好好的还顺手把事务、权限、混合查询这些老手艺全带过来了。一套数据库解决所有问题这话说得太满我不学。但对中等规模的 AI 应用我的建议就一句先别急着上第三套存储看看手头的库能不能把向量装下多半能省出一条同步链路外加好几个不眠之夜。下一步打算把工单的时序数据也并进来让检索结果带上这故障最近是不是高发的判断。库就在那儿一张表的事儿。老徐说了这回他等着看。