接口性能优化之 -----PageHelper

文章讲述了在项目中遇到的一个复杂接口由于涉及大量数据和联表查询导致性能下降,特别是PageHelper的计数操作缓慢。为了解决这个问题,作者重写了SQL查询,通过条件判断避免不必要的联表操作,从而提高了count查询的效率。这种方法在保持原有代码不变的情况下,只需要在MyBatis的XML文件中添加一个特定的_count查询,并确保PageHelper版本在5.0.5以上。
摘要由CSDN通过智能技术生成

问题描述

项目中一个复杂的接口耗时过高,查询的表数据量大,该接口使用了PageHelper进行查询结果进行分页,且该查询sql进行了 联表查询 。通过查看日志,将sql提出,发现是PageHelper组件在进行count计数的时候慢,而这个接口查询因为是分页且走了索引,反而并不慢。

PageHelper.startPage(searchRecordPosition.getPage(), searchRecordPosition.getSize());
List<positionRecordVO> result = positionRecordMapper.getRecordPositionList(searchRecordPosition);

这个是写的sql

<select id="getRecordPositionList" resultType="com.hengtiansoft.hzrc.dal.vo.positionRecordVO">
        SELECT p.id AS positionId,p.NAME AS positionName,p.education_id AS
        educationId,p.working_years_id AS workYearsId,p.recruit_number AS recruitNumber,
        p.high_tech as highTech,p.urgently_hired as urgentlyHired,r.id as recruitmentId,c.id as companyId,
        r.way as positionSource,r.name as recruitmentName,r.status as status,c.name as companyName,
        c.credit_code as creditCode,p.create_ts as releaseTs,
        p.tag_id AS tagId,p.s_region_id AS sRegionId,p.property as property,p.salary_lower as salaryLower,
        p.salary_max as salaryMax,p.contact as contact,p.contact_number as contactNumber,p.update_by as updateBy,r.id as
        recruitmentId
        FROM position_record p
        LEFT JOIN recruitment r ON p.recruitment_id = r.id
        LEFT JOIN company c ON p.company_id = c.id
        <where>
            <if test="null != searchPosition.educationId and searchPosition.educationId != ''">
                AND p.education_id = #{searchPosition.educationId}
            </if>
            <if test="searchPosition.companyId != null  and searchPosition.companyId != ''">
                and p.company_id = #{searchPosition.companyId}
            </if>
            <if test="searchPosition.positionName != null and searchPosition.positionName != ''">
                and p.name LIKE CONCAT('%',#{searchPosition.positionName},'%')
            </if>
            <if test="searchPosition.companyName != null and searchPosition.companyName != ''">
                and c.name LIKE CONCAT('%',#{searchPosition.companyName},'%')
            </if>
            <if test="searchPosition.startTime != null and searchPosition.endTime != null">
                and p.release_ts<![CDATA[>=]]> #{searchPosition.startTime}
                and p.release_ts <![CDATA[<=]]> #{searchPosition.endTime}
                and p.status != '1'
            </if>
            <if test="searchPosition.createStartTs !=null ">
                and p.create_ts <![CDATA[>=]]> #{searchPosition.createStartTs}
            </if>
            <if test="searchPosition.createEndTs !=null ">
                and p.create_ts <![CDATA[<=]]> #{searchPosition.createEndTs}
            </if>
            <if test="searchPosition.property !=null and searchPosition.property != ''">
                and p.property = #{searchPosition.property}
            </if>
            <if test="searchPosition.salaryMax !=null and searchPosition.salaryMax != ''">
                and p.salary_max <![CDATA[<=]]> #{searchPosition.salaryMax}
            </if>
            <if test="searchPosition.salaryLower !=null and searchPosition.salaryLower != ''">
                and p.salary_lower <![CDATA[>=]]> #{searchPosition.salaryLower}
            </if>
            <if test="searchPosition.workingYearsId !=null and searchPosition.workingYearsId != ''">
                and p.working_years_id = #{searchPosition.workingYearsId}
            </if>
            <if test="searchPosition.sRegionId !=null and searchPosition.sRegionId != ''">
                and p.s_region_id = #{searchPosition.sRegionId}
            </if>
            <if test="searchPosition.urgentlyHired !=null and searchPosition.urgentlyHired != ''">
                and p.urgently_hired = #{searchPosition.urgentlyHired}
            </if>
            <if test="searchPosition.tagId != null and searchPosition.tagId != ''">
                and p.tag_id = #{searchPosition.tagId}
            </if>
            <if test="searchPosition.recruitmentName != null and searchPosition.recruitmentName != ''">
                and r.name LIKE CONCAT('%',#{searchPosition.recruitmentName},'%')
            </if>
            <if test="searchPosition.positionSource !=null and searchPosition.positionSource != ''">
                and r.way = #{searchPosition.positionSource}
            </if>
            <if test="searchPosition.status !=null and searchPosition.status != ''">
                and r.status = #{searchPosition.status}
            </if>
        </where>
        order by p.create_ts desc
    </select>

解决方案

问题出在count上,而count慢其实是因为联表,所以我选择重写count,利用if标签,避免联表,做条件查询的时候,由于做了筛选,数据量会小很多,所以不慢

<select id="getRecordPositionList_COUNT" resultType="Long">
        SELECT count(*)
        FROM position_record p
        <if test="searchPosition.recruitmentName != null and searchPosition.recruitmentName != '' and searchPosition.positionSource !=null and searchPosition.positionSource != '' and searchPosition.status !=null and searchPosition.status != ''">
            LEFT JOIN recruitment r ON p.recruitment_id = r.id
        </if>
        <if test="null != searchPosition.companyName and searchPosition.companyName != ''">
            LEFT JOIN company c ON p.company_id = c.id
        </if>
        <where>
            <if test="null != searchPosition.educationId and searchPosition.educationId != ''">
                AND p.education_id = #{searchPosition.educationId}
            </if>
            <if test="searchPosition.companyId != null  and searchPosition.companyId != ''">
                and p.company_id = #{searchPosition.companyId}
            </if>
            <if test="searchPosition.positionName != null and searchPosition.positionName != ''">
                and p.name LIKE CONCAT('%',#{searchPosition.positionName},'%')
            </if>
            <if test="searchPosition.companyName != null and searchPosition.companyName != ''">
                and c.name LIKE CONCAT('%',#{searchPosition.companyName},'%')
            </if>
            <if test="searchPosition.startTime != null and searchPosition.endTime != null">
                and p.release_ts<![CDATA[>=]]> #{searchPosition.startTime}
                and p.release_ts <![CDATA[<=]]> #{searchPosition.endTime}
                and p.status != '1'
            </if>
            <if test="searchPosition.createStartTs !=null ">
                and p.create_ts <![CDATA[>=]]> #{searchPosition.createStartTs}
            </if>
            <if test="searchPosition.createEndTs !=null ">
                and p.create_ts <![CDATA[<=]]> #{searchPosition.createEndTs}
            </if>
            <if test="searchPosition.property !=null and searchPosition.property != ''">
                and p.property = #{searchPosition.property}
            </if>
            <if test="searchPosition.salaryMax !=null and searchPosition.salaryMax != ''">
                and p.salary_max <![CDATA[<=]]> #{searchPosition.salaryMax}
            </if>
            <if test="searchPosition.salaryLower !=null and searchPosition.salaryLower != ''">
                and p.salary_lower <![CDATA[>=]]> #{searchPosition.salaryLower}
            </if>
            <if test="searchPosition.workingYearsId !=null and searchPosition.workingYearsId != ''">
                and p.working_years_id = #{searchPosition.workingYearsId}
            </if>
            <if test="searchPosition.sRegionId !=null and searchPosition.sRegionId != ''">
                and p.s_region_id = #{searchPosition.sRegionId}
            </if>
            <if test="searchPosition.urgentlyHired !=null and searchPosition.urgentlyHired != ''">
                and p.urgently_hired = #{searchPosition.urgentlyHired}
            </if>
            <if test="searchPosition.tagId != null and searchPosition.tagId != ''">
                and p.tag_id = #{searchPosition.tagId}
            </if>
            <if test="searchPosition.recruitmentName != null and searchPosition.recruitmentName != ''">
                and r.name LIKE CONCAT('%',#{searchPosition.recruitmentName},'%')
            </if>
            <if test="searchPosition.positionSource !=null and searchPosition.positionSource != ''">
                and r.way = #{searchPosition.positionSource}
            </if>
            <if test="searchPosition.status !=null and searchPosition.status != ''">
                and r.status = #{searchPosition.status}
            </if>
        </where>
    </select>

使用方式

原有的代码不需要动,只需要在mybatis的xml文件里添加一个count查询
这里注意以下三点即可:

1.id和对应的查询语句保持一致,并且以 _COUNT 结尾,注意大小写
2.入参和对应的查询语句保持一致
3.出参为 resultType=“Long”
4.PageHelper的版本一定要在 5.0.5 以上

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值