MySql语句SUM、MAX优化:数据库版本5.7.26
为了避免大家误会,我用*直接代替了,也就是三个表查询出来的内容都是不能省略的。
SELECT * FROM khxx a
inner JOIN
(SELECT YXTKHH,HXJGBM,sum(jjye) AS jjye FROM dkxx GROUP BY YXTKHH,HXJGBM) c ON a.HXJGBM=c.HXJGBM AND a.YXTKHH=c.YXTKHH
left JOIN
(SELECT JKRXZ,update_time,SFNCZ, YXTKHH,HXJGBM FROM gqc WHERE id IN (SELECT max(id) FROM gqc GROUP BY YXTKHH,HXJGBM)) b ON a.YXTKHH=b.YXTKHH AND a.HXJGBM=b.HXJGBM
用到了 all 和 Using temporary; Using filesort,如何优化?
把a表放到后面?
题主给的语句是:
SELECT a.* FROM khxx a
inner JOIN (SELECT KHXX_ID ,sum(jjye) AS jjye FROM dkxx GROUP BY KHXX_ID) c ON a.ID=c.KHXX_ID
left JOIN (SELECT ID,khxx_id FROM gqc WHERE id IN (SELECT max(id) FROM gqc GROUP BY KHXX_ID ) ) b ON a.ID=b.KHXX_ID
这里面select的字段只有 a.*,不包含b和c的信息,又由于left join b的时候没有带任何where条件,因此a表的数据会全部保留,那么join b就没有意义了,首先可以砍掉b表的关联,变成:
SELECT a.* FROM khxx a
inner JOIN (SELECT KHXX_ID ,sum(jjye) AS jjye FROM dkxx GROUP BY KHXX_ID) c ON a.ID=c.KHXX_ID
再看这条语句里面, a inner join c 的条件是 c.KHXX_ID,再没有其他条件及where,所以c表的子查询中sum(jjye)没有意义,可以砍掉,再看看group by KHXX_ID并没有带任何where条件,因此dkxx表中的所有KHXX_ID在子查询中都会被保留下来,因此,子查询没有意义,可以直接用表dkxx进行关联,最终砍成:
SELECT a.* FROM khxx a
inner JOIN dkxx c ON a.ID=c.KHXX_ID
如果题主给出的sql语句正确表达了题主的意思,那么最终优化的语句就是这个了。
望采纳,谢谢!
子查询改成视图, 然后再拿视图去关联, 比如
create view c as SELECT YXTKHH,HXJGBM,sum(jjye) AS jjye FROM dkxx GROUP BY YXTKHH,HXJGBM
创建视图可参考: http://c.biancheng.net/view/2584.html
SELECT * FROM khxx a
left JOIN
(SELECT JKRXZ,update_time,SFNCZ, YXTKHH,HXJGBM FROM gqc WHERE id IN (SELECT max(id) FROM gqc GROUP BY YXTKHH,HXJGBM)) b ON a.YXTKHH=b.YXTKHH AND a.HXJGBM=b.HXJGBM
JOIN
(SELECT YXTKHH,HXJGBM,sum(jjye) AS jjye FROM dkxx GROUP BY YXTKHH,HXJGBM) c ON a.HXJGBM=c.HXJGBM AND a.YXTKHH=c.YXTKHH
这么写没什么问题,你是觉得运行时间长了,还是运行的结果不是你想要的
提供参考实例思路【mysql查询优化--临时表和文件排序(Using temporary; Using filesort问题解决)】,链接:https://www.cnblogs.com/jpfss/p/9156422.html
语句中包含了一个内连接和一个左连接。内连接用于将 dkxx 表中的数据与 khxx 表中的数据进行连接,并将 dkxx 表中的 jjye 字段按 YXTKHH 和 HXJGBM 分组求和。左连接用于将 gqc 表中的数据与 khxx 表中的数据连接,并将 gqc 表中的 id 字段按 YXTKHH 和 HXJGBM 分组取最大值。
您可以使用以下方法来优化这条 MySQL 语句:
另外,您也可以尝试使用 EXPLAIN 命令来分析 MySQL 语句的执行计划,以了解 MySQL 如何执行语句,并找出可以优化的地方。
EXPLAIN SELECT * FROM khxx a
inner JOIN
(SELECT YXTKHH,HXJGBM,sum(jjye) AS jjye FROM dkxx GROUP BY YXTKHH,HXJGBM) c ON a.HXJGBM=c.HXJGBM AND a.YXTKHH=c.YXTKHH
left JOIN
(SELECT JKRXZ,update_time,SFNCZ, YXTKHH,HXJGBM FROM gqc WHERE id IN (SELECT max(id) FROM gqc GROUP BY YXTKHH,HXJGBM)) b ON a.YXTKHH=b.YXTKHH AND a.HXJGBM=b.HXJGBM;
不要一条语句查询出所有的,跟据业务需求把sql拆开分几次查询。
这是一个使用内连接和左连接的 SQL 查询语句,它将 khxx、dkxx、gqc 三个表进行了连接。
为了优化这个查询,可以考虑以下几点:
使用索引来提升查询性能。在 khxx、dkxx 和 gqc 表中,可以建立 YXTKHH 和 HXJGBM 列的索引,这样可以更快地对这些列进行排序和过滤。
对于 dkxx 表,在进行 group by 操作时可以考虑使用索引来代替临时表。例如,可以在 dkxx 表上建立 (YXTKHH, HXJGBM, jjye) 的联合索引,然后使用索引上的 jjye 列计算 sum。
对于 gqc 表,在查询最大 id 时可以使用 limit 子句来限制返回的行数。例如:
SELECT * FROM gqc WHERE id IN (SELECT max(id) FROM gqc GROUP BY YXTKHH,HXJGBM LIMIT 100)
这样可以避免对整张表进行 group by 操作,从而提升查询性能。
对于 khxx 和 gqc 表,在使用左连接时,可以将它们放在连接的右侧,这样可以避免在左表中的 null 值对结果的影响。例如:
SELECT * FROM
(SELECT YXTKHH,HXJGBM,sum(jjye) AS jjye FROM dkxx GROUP BY YXTKHH,HXJGBM) c
INNER JOIN khxx a ON a.HXJGBM=c.HXJGBM AND a.YXTKHH=c.YXTKHH
LEFT JOIN
使用 EXPLAIN 分析查询的执行计划可以帮助优化查询。这两个标识表示 MySQL 需要使用临时表来执行查询,或者在查询结束时对结果进行排序。这可能会导致查询运行得更慢。
要优化查询,你可以尝试以下方法:
1.尽量避免使用 SELECT *,而是只选择需要的列。
2.为使用的列创建索引。
3.尽量使用带有谓词的查询,例如 WHERE 和 HAVING 子句。
4.尝试使用不同的查询方法,例如使用 JOIN 代替子查询。
5.如果你的查询在执行时需要排序,请尝试使用 ORDER BY 子句而不是 GROUP BY。
6.使用 LIMIT 子句可以帮助你限制查询返回的行数。
7.如果你的数据量非常大,可以考虑使用分区表来分割数据。
此外,还可以使用 MySQL 的性能分析工具,例如 PERFORMANCE_SCHEMA 或 EXPLAIN FORMAT=JSON,来更深入地了解查询的执行情况。