-背景

假如你遇到业务功能访问变慢,请确认是否涉及多表联合查询,是否是多表联合查询导致响应变慢

-关键字

SQL  JOIN连接 多表  变慢

-分析

1、多表连接首先LEFT JOIN或RIGHT JOIN首推,先排除这个

2、多表数量是否可以减少,比如连接五张表,分析后减少到三张表

3、最重要的,是否有全表扫描

-方案

只针对第三条说明,所有的多表慢问题,都是命中太多主表数据,笛卡尔积太大,只需要AxBxC的时候,筛选主表数据是根据解决之道。

-实现

		StringBuffer sqlSB = new StringBuffer(SqlFactory.Rsql(request, "BIZ_WORKORDER_RESULT"));
		//--------构造从表筛选条件到主表条件中,以解决联合查询变慢问题 Start------------//
		StringBuffer wpJoinWhere = new StringBuffer("");
		List<String> wpJoinWhereFieldList = new ArrayList<String>();
		wpJoinWhereFieldList.add("WP_PRODUCT_CODE");
		wpJoinWhereFieldList.add("WP_PRODUCT_BATCH");
		wpJoinWhereFieldList.add("WP_PLAN_TYPE_CODE");
		wpJoinWhereFieldList.add("WP_STATE");
		String tempJoinWhereStr = null;
		for (int i = 0; i < wpJoinWhereFieldList.size(); i++) {
			tempJoinWhereStr = request.getParameter(wpJoinWhereFieldList.get(i));
			if(StringUtils.isNotBlank(tempJoinWhereStr)){
				if(StringUtils.isNotBlank(wpJoinWhere)){
					wpJoinWhere.append(" and ");
				}
				wpJoinWhere.append(wpJoinWhereFieldList.get(i).replace("WP_", "")+" like '"+tempJoinWhereStr+"%'");
			}
		}
		if(StringUtils.isNotBlank(wpJoinWhere)){
			sqlSB.append(String.format(" and workshop_plan_id in (select id from BIZ_WORKSHOP_PLAN where %s) ",wpJoinWhere));
		}
		//--------------构造从表筛选条件到主表条件中,以解决联合查询变慢问题 End--------------------//
		P.rTablesPageJson(sqlSB.toString(), request);
--主表通过代码进行条件筛选,从表只做目标数据关联,将彻底解决变慢问题
select *
  from (select *
          from (select rownum as seq, p.*
                  from (select *
                          from BIZ_WORKORDER_RESULT
                         where is_completed like '%0%'
                           and is_submit like '%1%'
                           and workshop_plan_id in
                               (select id
                                  from BIZ_WORKSHOP_PLAN
                                 where STATE like '1%')) p)
         where seq > 20
           and seq <= 40
         order by sort, product_number, create_date desc) t1
  left join (select table_id,
                    wm_concat(dept_id) dept_ids,
                    wm_concat(dept_name) dept_names
               from BIZ_COMMON_DEPT
              where table_name = 'BIZ_WORKORDER_RESULT'
              group by table_id) t2
    on t2.table_id = t1.id
  left join (select table_id,
                    wm_concat(workgroup_id) workgroup_ids,
                    wm_concat(workgroup_name) workgroup_names
               from BIZ_COMMON_WORKGROUP
              where table_name = 'BIZ_WORKORDER_RESULT'
              group by table_id) t3
    on t3.table_id = t1.id
  left join (select table_id,
                    wm_concat(emp_id) emp_ids,
                    wm_concat(emp_name) emp_names
               from BIZ_COMMON_EMP
              where table_name = 'BIZ_WORKORDER_RESULT'
              group by table_id) t4
    on t4.table_id = t1.id
  left join (select id                  as wp_id,
                    is_delete           as wp_is_delete,
                    create_user         as wp_create_user,
                    create_date         as wp_create_date,
                    sort                as wp_sort,
                    PRODUCTION_PLAN_ID  as wp_PRODUCTION_PLAN_ID,
                    product_plan_no     as wp_product_plan_no,
                    product_code        as wp_product_code,
                    product_name        as wp_product_name,
                    product_batch       as wp_product_batch,
                    plan_type_code      as wp_plan_type_code,
                    plan_type_name      as wp_plan_type_name,
                    total_number        as wp_total_number,
                    qualified_number    as wp_qualified_number,
                    unit                as wp_unit,
                    type                as wp_type,
                    end_date            as wp_end_date,
                    units_leader        as wp_units_leader,
                    units_leader_id     as wp_units_leader_id,
                    remark              as wp_remark,
                    state               as wp_state,
                    order_id            as wp_order_id,
                    mes_batch_id        as wp_mes_batch_id,
                    erp_batch_id        as wp_erp_batch_id,
                    project_name        as wp_project_name,
                    PRODUCT_ID          as wp_PRODUCT_ID,
                    ROUTING_NAME        as wp_ROUTING_NAME,
                    ROUTING_ID          as wp_ROUTING_ID,
                    ACTUAL_TOTAL_NUMBER as wp_ACTUAL_TOTAL_NUMBER
               from BIZ_WORKSHOP_PLAN) t5
    on t5.wp_id = t1.workshop_plan_id
  left join (select id                 as pp_id,
                    is_delete          as pp_is_delete,
                    create_date        as pp_create_date,
                    create_user        as pp_create_user,
                    plan_no            as pp_plan_no,
                    year_month         as pp_year_month,
                    production_unit    as pp_production_unit,
                    work_group         as pp_work_group,
                    units_leader       as pp_units_leader,
                    production_unit_id as pp_production_unit_id,
                    work_group_id      as pp_work_group_id,
                    units_leader_id    as pp_units_leader_id,
                    state              as pp_state
               from BIZ_PRODUCTION_PLAN) t6
    on t6.pp_id = t5.wp_PRODUCTION_PLAN_ID


-效果

从43268条主表数据查询一次2.78秒,提高到0.016秒。