需求更改实现方式提升效率
早就想写但是最近一直忙,好容易抽出来空写一篇记录一下。
需求
一个给的荣誉墙的业务,大概是三个表,一个表honor_data是具体的荣誉名称以及具体的人员信息,一个表honor_dimension是荣誉的维度,荣誉一共是三个维度,honor_certificate是证书的表
分析
其实在设计的时候没有想的那么麻烦,所以设计的时候其实是一对一的,honor_data表对应着一条的honor_dimension,对应这样一条的honor_certificate。
不出意外的是意外发生了,因为维度表是三个维度,所以是直接在维度表加的字段,类似第一级维度,第二级维度,第三季维度,都在数据表honor_dimension的同一条记录中,但是客户给的导入数据我们实现导入的时候出现了问题。客户给的数据没有第三级的维度,就导致了数据没有办法给定,最开始的维度表设计是这样的
CREATE TABLE `honor_dimension` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`dimension` VARCHAR(50) DEFAULT NULL COMMENT '维度',
`one_dimension` VARCHAR(100) DEFAULT NULL COMMENT '一级维度',
`two_dimension` VARCHAR(100) DEFAULT NULL COMMENT '二级维度',
`sort` INT(11) DEFAULT NULL COMMENT '子序',
`behavioral_interpretation` VARCHAR(300) DEFAULT NULL COMMENT '行为解释',
`identify_basis` VARCHAR(50) DEFAULT NULL COMMENT '认定依据',
`identify_department` VARCHAR(50) DEFAULT NULL COMMENT '认定部门',
`enable` TINYINT(1) DEFAULT '1' COMMENT '状态,1启用;0禁用',
`remark` VARCHAR(100) DEFAULT NULL COMMENT '备注',
`create_by` BIGINT(20) DEFAULT NULL COMMENT '创建者',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`create_by_org` BIGINT(20) DEFAULT NULL COMMENT '创建者组织',
`update_by` BIGINT(20) DEFAULT NULL COMMENT '修改者',
`update_time` DATETIME DEFAULT NULL COMMENT '修改时间',
`update_by_org` BIGINT(20) DEFAULT NULL COMMENT '修改者组织',
`is_deleted` TINYINT(1) DEFAULT '0' COMMENT '是否删除,1 是;0否',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='山东联通员工行为认可维度表';
然后就开始了问题了,我们需要拆分维度,并且要有父子级别关系,还好是级别够低不需要而外的其他的字段。
创建新的表结构
create table honor_dimension
(
id int auto_increment comment '主键ID'
primary key,
dimension varchar(50) null comment '维度',
parent_id int null comment '父节点ID',
sort int null comment '子序号',
behavioral_interpretation varchar(300) null comment '行为解释',
identify_basis varchar(50) null comment '认定依据',
identify_department varchar(50) null comment '认定部门',
enable tinyint(1) default 1 null comment '状态,1启用;0禁用',
remark varchar(100) null comment '备注',
create_by varchar(36) null comment '创建者',
create_date datetime default CURRENT_TIMESTAMP null comment '创建时间',
create_by_org bigint null comment '创建者组织',
update_by varchar(36) null comment '修改者',
update_date datetime null comment '修改时间',
update_by_org bigint null comment '修改者组织',
delete_flag varchar(16) null comment '逻辑删除位,normal表示正常,deleted表示删除'
)
其实到这里来说是一个小问题,大问题来了,我需要展示个人荣誉,个人荣誉有两块,第一块是需要展示个人荣誉,第二块是要展示个人所在部门的所有荣誉,正常思路,求出一个员工列表,计算出其中的维度情况,因为目前数据只有二级维度,所以在计算维度的时候需要注意维度等级,但是偏偏没有维度等级字段,只能够通过递归。
@Override
public List<HonorDataVo> findHonorByEmployeeNumber(String employeeNumber) {
List<HonorDataVo> employeeNumberListRet = new ArrayList<>();
List<HonorDataVo> employeeNumberList = honorWallMapper.findHonorByEmployeeNumber(employeeNumber);
for (int i = 0; i < employeeNumberList.size(); i++) {
HonorDataVo honorDataVo = employeeNumberList.get(i);
int dimensionId = honorDataVo.getDimensionId();
HonorDimension honorDimensionByid = honorWallMapper.findHonorDimensionByid(dimensionId);
List HonorDimensionList = new ArrayList();
if (null != honorDimensionByid) {
HonorDimensionList.add(honorDimensionByid);
while (honorDimensionByid.getParentId() != 0) {
honorDimensionByid = honorWallMapper.findHonorDimensionByid(honorDimensionByid.getParentId());
HonorDimensionList.add(honorDimensionByid);
}
}
honorDataVo.setHonorDimensionList(HonorDimensionList);
HonorCertificate honorCertificateByid = honorWallMapper.findHonorCertificateByid(honorDataVo.getCertificateId());
honorDataVo.setHonorCertificate(honorCertificateByid);
employeeNumberListRet.add(honorDataVo);
}
return employeeNumberListRet;
}
employeeNumberList 是求出的对应的员工的集合,honor_dimension表的parent_id等于0就是最父级的那个,最开始这么写的时候,这个接口请求的时候7s多,加完了索引大概是4s多,还是效率低,然后换了种写法,将递归操作放在了数据中。
@Override
public List<HonorDataVo> findHonorByEmployeeNumber(Map<String, Object> params) {
String employeeNumber = String.valueOf(params.get("employeeNumber"));
String returnType = String.valueOf(params.get("returnType"));
List<HonorDataVo> employeeNumberListRet = new ArrayList<>();
List<HonorDataVo> employeeNumberList;
if ("1".equals(returnType)) {
employeeNumberList = honorWallMapper.findHonorByOrg5(employeeNumber);
} else if ("2".equals(returnType)) {
employeeNumberList = honorWallMapper.findHonorByEmployeeNumber(employeeNumber);
} else {
return null;
}
for (HonorDataVo honorDataVo : employeeNumberList) {
int dimensionId = honorDataVo.getDimensionId();
List<HonorDimension> honorDimensionByid = honorWallMapper.findHonorDimensionListByid(dimensionId);
honorDataVo.setHonorDimensionList(honorDimensionByid);
HonorCertificate honorCertificateByid = honorWallMapper.findHonorCertificateByid(honorDataVo.getCertificateId());
honorDataVo.setHonorCertificate(honorCertificateByid);
employeeNumberListRet.add(honorDataVo);
}
return employeeNumberListRet;
}
<select id="findHonorDimensionListByid" resultType="cn.chinaunicom.sdsi.talent.entity.HonorDimension">
SELECT T2.id,T2.dimension,T2.parent_id
FROM (
SELECT
@r AS _id,
(SELECT @r := honor_dimension.parent_id FROM saas_dhr.honor_dimension WHERE id = _id) AS pid,
@l := @l + 1 AS lvl
FROM
(SELECT @r := #{id}, @l := 0) vars,
saas_dhr.honor_dimension h
WHERE @r <> 0) T1
JOIN saas_dhr.honor_dimension T2
ON T1._id = T2.id
ORDER BY T1.lvl
</select>
不过这个更换了之后没有啥用,其实也就是3-4s左右,时间还是很长,后面想了想直接换了思路了,反正第三维度没有,我们不考虑了,直接left join 他的表就好了
<select id="findDimensionHonordata" parameterType="java.lang.String" resultType="java.util.Map">
select data.employee_number, data.employee_name,data.organization_name, data.honor_name,data.year,data.get_date,hd6.id1,hd6.name1,hd6.id2,hd6.name2
from saas_dhr.honor_data data
left join
(SELECT hd4.id as id1, hd4.dimension as name1, hd5.id as id2, hd5.dimension as name2
FROM (SELECT *
FROM saas_dhr.honor_dimension hd2
WHERE hd2.parent_id IN (SELECT id
FROM saas_dhr.honor_dimension hd3
WHERE hd3.parent_id = 0)) hd5
LEFT JOIN (SELECT *
FROM saas_dhr.honor_dimension hd1
WHERE hd1.parent_id = 0) hd4 ON hd5.parent_id = hd4.id) hd6
on data.dimension_id = hd6.id2
where employee_number = #{employeeNumber}
</select>
直接更换思路,然后速度直接到了300ms上下,该说不说思路的转变真的很难,花了很久很久才想到这个思路的,主要是陷入了误区了,也是因为这个递归级别低,所以可以只选前两个表进行处理,是一个馊主意,但是速度大大的提升了,我们的职业其实就是处理问题,虽然这个主意不是一个好的主意,但是问题确实处理了
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!