数据库是mysql5.7,帮我优化下这条sql:SELECT epi.business_id,epi.project_id,epi.product_setmeal_id,count(1) num FROM emp_info ei LEFT JOIN (select epi.* from emp_project_info epi where epi.status = 1 AND epi.is_across = 0 AND epi.start_date = ( SELECT max( start_date ) FROM emp_project_info WHERE STATUS = 1 AND emp_id = epi.emp_id AND project_id = epi.project_id AND start_date <= '2023-05-01 00:30:00.028' and is_across = 0 ) AND epi.begin_date <= '2023-05-01 00:30:00.028' AND (epi.end_date is null or epi.end_date > '2023-05-01 00:30:00.028')) epi ON ei.id = epi.emp_id WHERE ei.status = 1 AND ei.type = 3 AND epi.project_id is not null AND epi.source != 5 GROUP BY epi.business_id,epi.project_id,epi.product_setmeal_id
时间: 2024-03-29 19:36:50 浏览: 134
为了优化这个 SQL,你可以考虑以下几点:
1. 将子查询用 JOIN 替代,以避免多层嵌套子查询的性能问题。
2. 为了避免子查询的重复计算,可以将子查询的结果保存到临时表中,并在 JOIN 时使用该临时表。
3. 需要为 emp_project_info 表添加合适的索引,以加快查询速度。
优化后的 SQL 如下:
先创建临时表:
CREATE TEMPORARY TABLE temp_ep_info AS
SELECT emp_id, project_id, product_setmeal_id, MAX(start_date) AS max_start_date
FROM emp_project_info
WHERE status = 1 AND is_across = 0 AND begin_date <= '2023-05-01 00:30:00.028' AND (end_date IS NULL OR end_date > '2023-05-01 00:30:00.028')
GROUP BY emp_id, project_id, product_setmeal_id;
然后执行查询:
SELECT epi.business_id, epi.project_id, epi.product_setmeal_id, COUNT(1) num
FROM emp_info ei
LEFT JOIN temp_ep_info tei ON ei.id = tei.emp_id
LEFT JOIN emp_project_info epi ON tei.emp_id = epi.emp_id AND tei.project_id = epi.project_id AND tei.product_setmeal_id = epi.product_setmeal_id AND tei.max_start_date = epi.start_date
WHERE ei.status = 1 AND ei.type = 3 AND epi.project_id IS NOT NULL AND epi.source != 5
GROUP BY epi.business_id, epi.project_id, epi.product_setmeal_id;
这样就可以避免多层嵌套子查询的性能问题,并且通过使用临时表来避免子查询的重复计算。同时,在 emp_project_info 表上添加合适的索引也可以提高查询速度。
阅读全文