读取连接表生成CSV两种方案之比较
前篇:https://www.cnblogs.com/heyang78/p/15860075.html
【需求】
目标系统存在三张表,用户表Customer,最大有两百万数据;标记表tag,一开始定为10000个,后来改为1600个;两者的连接表Customer_Tag,这个数据多,最多时为2,000,000*1600=32,0000,0000条。现在需要将每个用户拥有的tag以csv的形式输出出来,tag存在标1,Tag不存在标0,中间以逗号分隔。
比如总共有10个tag,用户A拥有tagid=1,3,5,7,9的tag,那么该输出这样的数据:
A,1,0,1,0,1,0,1,0,1,0
其它数据类推
【实现比较】
原有方案 | 新方案 | |
思路 |
读取连接表,按用户id获得所有tagid,然后用listagg将tagid串起来。 在Python中劈分tagid串,重组成0,1,1,0这种形式。 |
读取三张表,连续连接三张表,最终形成customername,0,1,0,1,0...的形式 |
SQL处理部分 | 读取连接表,按用户id获得所有tagid,然后用listagg将tagid串起来。 | 绝大部分业务 |
SQL |
select a.name,b.tags from |
select ct.name,f.tags as line from ( select e.cid,listagg(e.tg,',') within group (order by e.sn) as tags from ( select c.cid,c.sn, decode(nvl(d.tid,0),0,'0','1') as tg from (select a.sn,a.val,b.id as cid from (select level as sn,'0' as val from dual connect by level<=1000) a, (select id from customer where 10000<id and id<=20000) b ) c left join (select * from customer_tag where 10000<cid and cid<=20000) d on c.cid= d.cid and c.sn=d.tid ) e group by e.cid ) f left join customer ct on f.cid=ct.id order by f.cid |
Python处理部分 | 创建1-1000的序列,劈分tagid串,按下标到序列中改0为1,这一步相当于数组位操作,很快。 | 只用将用户名和tag连起来。 |
耗时 | 82秒 | 162秒 |
优势 | 整体耗时少,tagid累加时完全不用排序 | 无论在实验环境(1000个tag)和实际环境(1600个tag)都无需担心超listagg上限的问题 |
劣势 | tagid累加时可能超4000上限 | 整体耗时长,每个customer对应的tag都要排序是耗时瓶颈所在。 |
源码 | https://www.cnblogs.com/pyhy/p/15855992.html | https://www.cnblogs.com/pyhy/p/15862430.html |
以上试验在T440p,Oracle11G上进行。
分类:
Oracle.权衡比较Sql文
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
2019-02-04 【Canvas与密铺】正六边形、正方形和正三角形的密铺