之前谈了怎样后台导出SAP序时账,因为导出的序时账数据量较大(3家主体公司,2017-2020年的数据),用了数据库MYSQL中的LEFT JOIN 来处理连接多表汇总数据,查询太慢啦,后来沦落到用手工分年来汇总数据,然后再导到MYSQL进行数据查询分析,惨兮兮,宝宝真的很生气,今天我就在项目结束后来搞一搞原因,为什么会这么慢?
01
背景
首先说下项目背景,从SAP后台导出了与会计凭证相关的两张表,两张表分别是BSEG(分字段导了两次)和BKPF,明细字段结构如下所示:



我现在的目标是把三张表数据拼成一张表数据,即一条完整的凭证,最终应当实现的结果为:

02
解决思路
我理了下处理这三张表数据的思路:
1、将BSEG1和BSEG2这两张表数据以公司、年度、凭证编号、项这4个字段为索引连接起来,得到一个完整的BSEG表;
2、将BSEG表和BKPF表这两张表数据以公司、年度、凭证编号这3个字段为索引连接起来,得到一个完整的凭证表。
步骤1:下面我来进行上述问题解决思路的第一个步骤,用到了以下语句,我用10条以内的数据试了一下,花了0.003秒,这个语句完美的实现了我的需求,而且在ON后面对4个条件加上括号实现的结果也完全一样,如下所示:
SELECT * FROM bseg2 t LEFT JOIN bseg1 s
ON (s.公司=t.公司1
and s.凭证号码=t.凭证号码1
and s.年度=t.年度1
and s.项=t.项1)

可是我的BSEG表1和BSEG表2 分别包含了104,2033条和104,4095条数据,百万行数据4个条件同时LEFT JOIN,项目进行的时候我试过了,一下午没跑出来,要是我去客户公司对面的那座山去溜几圈,可能都已经回来了……
好了,我改变方法了,把4个条件字段连接起来单独插入一列,分别构成两张表的主键(意思是该列元素均为唯一且不为空),用到了CONCAT语句,可以把多个字段的信息连接起来。例如:SELECT CONCAT('M','y','S','Q','L')——该语句的执行结果为MYSQL ;那么现在我的问题就转化成了,以ORDER_NO字段连接BSEG1和BSEG2数据,由原来的4个连接条件变成了1个连接条件。

好的,在连接两表数据前还有关键的一步,添加索引,添加索引的效果是可以加快查询速度,添加主键索引我用到了以下语句,意思是为表BSEG1的ORDER_NO 字段添加索引,添加索引真的得用语句来加索引,数据量大千万不能用设计表的那个傻瓜式图形界面来添加,我试过,设计表图形界面添加索引,会让你的MYSQL停留在那个界面,完全卡死。语句添加索引我忘了截图完成时间,几十秒。
ALTER TABLE bseg1 PRIMARY KEY (order_no)
见证奇迹的时刻到了,把LEFT JOIN写上去,以ORDER_NO连接两表数据。26.541s,哼,亮瞎了我的眼,又高兴又生气。

步骤2:我没有在MYSQL中操作把步骤一中得到的BSEG表和BKPF连接了,大致思路就是现在BKPF和BSEG连接有三个条件字段(公司、凭证编号、年度),解决方法参见步骤1.
03
写在最后
现在我开始吐槽了,我真的高兴,又有点生气,甚至说是不甘心。我手工汇了老半天,MYSQL你26s就给我跑出来了,想想就不甘心。然后我又试着说服自己,以后遇到这种问题,应该心里就有底了,唉,还是不甘心呐

去抖音看我跳舞喔!
公众号 : MOMO的笔记
抖音号:348785339