SQL多表联合查询最佳实践(数据量增加查询越来越慢)
作者:互联网
-背景
假如你遇到业务功能访问变慢,请确认是否涉及多表联合查询,是否是多表联合查询导致响应变慢
-关键字
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秒。
标签:多表,变慢,wpJoinWhereFieldList,查询,数据量,主表,select 来源: https://blog.51cto.com/zl0828/2794483