MyBatis 分页查询优化实例(用好子查询,事关功倍)

如下图所示的这种列表应该是系统里最常见的了。随着数据的增长,查询的速度也将越来越慢,那就需要优化了。
数据库使用的是mysql, 分页命名用的是mybatis plus 的paging插件。
MyBatis 分页查询优化实例(用好子查询,事关功倍)_第1张图片

优化的手段

  1. 加上条件限制,像这个页面应该加上时间范围限制,只能查一个月的或者一年的数据。
  2. SQL查询优化。

今天重点是讲怎么去优化SQL。

SQL优化

一:优化前

1:Mapper 代码

    <select id="getPages" resultType="com.ly.mp.swcas.main.entities.Retrospect">
        SELECT
        r.*,
        v.LOOKUP_VALUE_NAME,
        v.LOOKUP_VALUE_CODE,
        s.VIN
        FROM
        t_swcas_bu_retrospect As  r
        LEFT JOIN t_swcas_db_lookup_value As v ON r.RETROSPECT_PART_NO = v.LOOKUP_VALUE_CODE AND v.COMM_TYPE_CODE = 'swcas_trace_no'
        and r.IS_ENABLE=1
        LEFT JOIN t_swcas_bu_sale  As  s  ON  r.SAP_ORDER_NO = s.PLANNED_ORDER_NUMBER and s.IS_ENABLE=1
        <where>
        <if test="sapOrderNo != null and sapOrderNo !='' ">
            and r.SAP_ORDER_NO = #{sapOrderNo}
        if>
        <if test="mesProductionNo != null and mesProductionNo !=''">
            and r.MES_PRODUCTION_NO = #{mesProductionNo}
        if>
        <if test="retrospectPartNo != null and retrospectPartNo !='' ">
            and r.RETROSPECT_PART_NO = #{retrospectPartNo}
        if>
        <if test="vin != null and vin !='' ">
                and s.VIN = #{vin}
        if>
            <if test="lookUpValueName != null and lookUpValueName !='' ">
                and LOOKUP_VALUE_NAME = #{lookUpValueName}
            if>
        where>
    select>

2:使用mybatis plus分页会产成两个脚本(不使用任务条件的情况下)。分别是:

1):页数据查询

SELECT
        r.*,
        v.LOOKUP_VALUE_NAME,
        v.LOOKUP_VALUE_CODE,
        s.VIN
        FROM
        t_swcas_bu_retrospect As  r
        LEFT JOIN t_swcas_db_lookup_value As v ON r.RETROSPECT_PART_NO = v.LOOKUP_VALUE_CODE AND v.COMM_TYPE_CODE = 'swcas_trace_no'
        and r.IS_ENABLE=1
        LEFT JOIN t_swcas_bu_sale  As  s  ON  r.SAP_ORDER_NO = s.PLANNED_ORDER_NUMBER and s.IS_ENABLE=1 limit 10,10

2):总数查询

SELECT
	count(1)
FROM
	t_swcas_bu_retrospect AS r
LEFT JOIN t_swcas_db_lookup_value AS v ON r.RETROSPECT_PART_NO = v.LOOKUP_VALUE_CODE
AND v.COMM_TYPE_CODE = 'swcas_trace_no'
AND r.IS_ENABLE = 1
LEFT JOIN t_swcas_bu_sale AS s ON r.SAP_ORDER_NO = s.PLANNED_ORDER_NUMBER
AND s.IS_ENABLE = 1;

3):耗时结果

1 页数据查询很快,耗时0.003秒。
2 总数查询慢,耗时8秒。
数量为:80万。

结果如用户反馈一样,非常慢。。

分析

1:业务表分析

t_swcas_bu_retrospect 零件追溯表(开发环境80W数据,生产500W)
t_swcas_db_lookup_value 键值表 (数据量1000)
t_swcas_bu_sale 销售表(开发环境 30W, 生产100万)

SQL优化思路

1:t_swcas_bu_retrospect 、t_swcas_bu_sale 两个大表关联,实际上只为了取销售表里的一个字段。优化:使用子查询处理
2:与值列表关联使用inner join。确认是能一一对应上的。把r.IS_ENABLE = 1 放在 where 之后。
3:第2步去掉了 t_swcas_bu_sale 关联,那么 t_swcas_bu_sale 对应的条件也要处理。如下
and r.SAP_ORDER_NO in (select s.PLANNED_ORDER_NUMBER from t_swcas_bu_sale s where s.vin = #{vin})

结体SQL优化如下:

<select id="getPages" resultType="com.ly.mp.swcas.main.entities.Retrospect">
        SELECT
        r.*,
        v.LOOKUP_VALUE_NAME,
        v.LOOKUP_VALUE_CODE,
        v.EXT_COL01 AS LOOKUP_VALUE_EN_NAME,
        (select s.VIN from t_swcas_bu_sale s where  s.IS_ENABLE=1 and r.SAP_ORDER_NO = s.PLANNED_ORDER_NUMBER limit 1 ) as VIN
        FROM
        t_swcas_bu_retrospect As  r
        inner JOIN t_swcas_db_lookup_value As v ON r.RETROSPECT_PART_NO = v.LOOKUP_VALUE_CODE AND v.COMM_TYPE_CODE = 'swcas_trace_no'
        where  r.IS_ENABLE=1
        <if test="sapOrderNo != null and sapOrderNo !='' ">
            and r.SAP_ORDER_NO = #{sapOrderNo}
        if>
        <if test="mesProductionNo != null and mesProductionNo !=''">
            and r.MES_PRODUCTION_NO = #{mesProductionNo}
        if>
        <if test="retrospectPartNo != null and retrospectPartNo !='' ">
            and r.RETROSPECT_PART_NO = #{retrospectPartNo}
        if>
        <if test="vin != null and vin !='' ">
           and r.SAP_ORDER_NO in (select s.PLANNED_ORDER_NUMBER  from   t_swcas_bu_sale s where  s.vin = #{vin})
        if>
        <if test="lookUpValueName != null and lookUpValueName !='' ">
                and LOOKUP_VALUE_NAME = #{lookUpValueName}
        if>
        order by r.created_date desc
    select>

索引创建

1:根据排序字段创建索引

create index ix_t_swcas_bu_retrospect_CreatedDate on t_swcas_bu_retrospect  (created_date desc)

2:根据关联字字段创建索引

create index ix_t_swcas_bu_retrospect_RETROSPECT_PART_NO  on t_swcas_bu_retrospect  (RETROSPECT_PART_NO )

测试:

1:查询页数据,如下图所示,耗时16毫秒,符合要求。
MyBatis 分页查询优化实例(用好子查询,事关功倍)_第2张图片
2:查询总数,耗时0.6秒,符合优化条件。

MyBatis 分页查询优化实例(用好子查询,事关功倍)_第3张图片
优化完成。开发环境 页面响应少于2秒,业务环境 响应少于3秒。

你可能感兴趣的:(mysql,Java,mysql)