mysql - 需要优化查询

标签 mysql sql join

我在共享托管服务器中运行以下查询时遇到问题。执行时间设置为 10 秒,但我的查询时间很长,我无法更改它。

SELECT M.fecha_mov, -SUM(M.monto) monto, -SUM(M.interes) interes, -SUM(M.iva) iva, -SUM(M.capital) capital, 
B.banco, 
COALESCE(tg.nombre, tp.NombComp) nombreGrupo, CONCAT(nombres,' ',apellido_paterno,' ',apellido_materno) nombre, 
C.expediente, C.id_credito 
FROM movimientos M 
JOIN acreditados A ON A.id_acreditado=M.id_acreditado 
JOIN personas P ON P.id_persona=A.id_persona 
JOIN creditos C ON C.id_credito=A.id_credito 
JOIN abonos AB ON AB.id_movimiento=M.id_movimiento 
JOIN depositos_bancarios D ON D.id_deposito=AB.id_deposito 
JOIN cuentas_bancarias B ON B.id_banco=D.id_banco 
LEFT OUTER JOIN (SELECT R.id_credito, AG.nombre FROM representantes R JOIN agrupaciones AG USING (id_grupo)) tg ON tg.id_credito = C.id_credito 
LEFT OUTER JOIN (SELECT id_persona, CONCAT(nombres,' ',apellido_paterno,' ',apellido_materno) AS NombComp FROM personas) tp ON A.id_persona = tp.id_persona  
GROUP BY YEAR(M.fecha_mov), MONTH(M.fecha_mov), P.id_persona 
HAVING -SUM(M.monto) > 15000 
ORDER BY B.id_banco, M.fecha_mov, C.id_credito

我认为没有它们,两个左外连接都会导致问题,查询运行正常。我正在使用左外连接部分,因为只有 representantes 表的一些实例与 creditos 表有关系,所以在没有关系的情况下我使用连接角色表。

您认为这个查询可以优化吗?

更新

感谢 rcl 的@simon 和@Kickstart,查询得到了改进,删除了一个不需要的 LEFT OUTER JOIN 并删除了子查询

SELECT M.fecha_mov, -SUM(M.monto) monto, -SUM(M.interes) interes, -SUM(M.iva) iva, -SUM(M.capital) capital, 
B.banco, 
COALESCE(AG.nombre, CONCAT(nombres,' ',apellido_paterno,' ',apellido_materno)) nombreGrupo, 
CONCAT(nombres,' ',apellido_paterno,' ',apellido_materno) nombre, 
C.expediente, C.id_credito 
FROM movimientos M 
JOIN acreditados A ON A.id_acreditado=M.id_acreditado 
JOIN personas P ON P.id_persona=A.id_persona 
JOIN creditos C ON C.id_credito=A.id_credito 
JOIN abonos AB ON AB.id_movimiento=M.id_movimiento 
JOIN depositos_bancarios D ON D.id_deposito=AB.id_deposito 
JOIN cuentas_bancarias B ON B.id_banco=D.id_banco 
LEFT OUTER JOIN representantes R ON R.id_credito=C.id_credito
LEFT OUTER JOIN agrupaciones AG ON AG.id_grupo=R.id_grupo 
GROUP BY YEAR(M.fecha_mov), MONTH(M.fecha_mov), P.id_persona 
HAVING -SUM(M.monto) > 15000 
ORDER BY B.id_banco, M.fecha_mov, C.id_credito

更新

谢谢大家宝贵的提示,现在我可以在 1 秒内运行我的查询!我会按照建议发布我的查询计划,如果您有任何建议,请告诉我。老实说,我是查询计划方面的新手。

'1', 'SIMPLE', 'C', 'ALL', 'PRIMARY', NULL, NULL, NULL, '888', 'Using temporary; Using filesort'
'1', 'SIMPLE', 'R', 'ref', 'fk_representantes_creditos_idx', 'fk_representantes_creditos_idx', '4', 'creabien_sacredi_dev.C.id_credito', '1', ''
'1', 'SIMPLE', 'AG', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'creabien_sacredi_dev.R.id_grupo', '1', ''
'1', 'SIMPLE', 'A', 'ref', 'PRIMARY,FK_acreditados_personas,FK_acreditados_creditos', 'FK_acreditados_creditos', '4', 'creabien_sacredi_dev.C.id_credito', '2', ''
'1', 'SIMPLE', 'P', 'eq_ref', 'PRIMARY', 'PRIMARY', '4', 'creabien_sacredi_dev.A.id_persona', '1', ''
'1', 'SIMPLE', 'M', 'ref', 'PRIMARY,FK_movimientos_acreditados', 'FK_movimientos_acreditados', '4', 'creabien_sacredi_dev.A.id_acreditado', '10', ''
'1', 'SIMPLE', 'AB', 'ref', 'FK_abonos_depositos_bancarios,FK_abonos_movimientos', 'FK_abonos_movimientos', '8', 'creabien_sacredi_dev.M.id_movimiento', '1', ''
'1', 'SIMPLE', 'D', 'eq_ref', 'PRIMARY,FK_depositos_bancarios_cuentas_bancarias', 'PRIMARY', '8', 'creabien_sacredi_dev.AB.id_deposito', '1', ''
'1', 'SIMPLE', 'B', 'ALL', 'PRIMARY', NULL, NULL, NULL, '6', 'Using where; Using join buffer'

最佳答案

感谢所有评论,答案如下:

SELECT M.fecha_mov, -SUM(M.monto) monto, -SUM(M.interes) interes, -SUM(M.iva) iva, -SUM(M.capital) capital, 
B.banco, 
COALESCE(AG.nombre, CONCAT(nombres,' ',apellido_paterno,' ',apellido_materno)) nombreGrupo, 
CONCAT(nombres,' ',apellido_paterno,' ',apellido_materno) nombre, 
C.expediente, C.id_credito 
FROM movimientos M 
JOIN acreditados A ON A.id_acreditado=M.id_acreditado 
JOIN personas P ON P.id_persona=A.id_persona 
JOIN creditos C ON C.id_credito=A.id_credito 
JOIN abonos AB ON AB.id_movimiento=M.id_movimiento 
JOIN depositos_bancarios D ON D.id_deposito=AB.id_deposito 
JOIN cuentas_bancarias B ON B.id_banco=D.id_banco 
LEFT OUTER JOIN representantes R ON R.id_credito=C.id_credito
LEFT OUTER JOIN agrupaciones AG ON AG.id_grupo=R.id_grupo
GROUP BY YEAR(M.fecha_mov), MONTH(M.fecha_mov), P.id_persona 
HAVING -SUM(M.monto) > 15000 
ORDER BY B.id_banco, M.fecha_mov, C.id_credito

关于mysql - 需要优化查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21331023/

相关文章:

mysql - 无法创建 SQL 表 - 已定义错误 1005

php - 什么是 php 中纯全文搜索的快速替代方案?

Mysql查询多条件错误

powershell - PowerShell 中的内部联接(无 SQL)

php 脚本未正确传递值或未正确从 mysql 查询

sql - StartsWith() 在 LINQ 中不会转换为 Like ('abc%' )

sql - 从 SQL Server 中的表的每一行中获取单词 `href` 和 `nofollow` 的计数

PHP在函数中添加多个JOIN方法

python - 使用 join 在 python 中创建字典

sql - Postgresql 将属性与表混淆