繁体   English   中英

如何优化此查询MySQL

[英]How to optimize this Query MySQL

我有这个MySQL查询,但速度很慢。

SELECT
        d.idcartera,
        concat(d.cedula, ':', planilla.fuerza, ':', planilla.cuotas, ':', d.libranza, ':',   planilla.promotor) AS ClienteCedula,
        concat(d.nombres, ':', planilla.fuerza, ':', planilla.cuotas, ':', d.libranza, ':', planilla.promotor) AS ClienteNombre,
        d.valor,
        d.tipo,
        concat(d.ano, '/', d.mes, '-', left(d.tipo,3)) AS anoMes,
        planilla.fuerza,
        planilla.cuotas,
        planilla.promotor
        FROM cartera AS d
       INNER JOIN cartera AS x ON d.cedula = x.cedula
       INNER JOIN cartera AS y ON d.cedula = y.cedula
       INNER JOIN planilla ON d.libranza = planilla.libranza
        WHERE (d.tipo not like '%RI-%') AND (left(x.tipo, 3) like 'RC-') AND (left(y.tipo, 3) like 'RCN')
        GROUP BY d.idcartera, d.cedula

对不起,“ y”表是过滤一些数据

对于查询的第一部分(对Cartera AS d进行查询和分组),应考虑以下索引:

CREATE index i1a ON cartera(cedula, idcartera, tipo, liberanza);
CREATE index i1b ON cartera(idcartera, cedula, tipo, liberanza);

要么

CREATE index i1c ON cartera(tipo, idcartera, cedula, liberanza); 

(取决于您的DBMS,是否可以将“ left / like” -Operation应用于索引列技巧。

对于x和y的连接,您应该添加以下索引(如果尚未添加PK):

CREATE index i2 ON cantera(cedula) (if you will use i1b or i1c)

对于planilla上的联接,在planilla(liberanza)上添加CREATE INDEX i3(如果尚未PK)

这是您的查询:

SELECT d.idcartera,
       concat(d.cedula, ':', planilla.fuerza, ':', planilla.cuotas, ':', d.libranza, ':',   planilla.promotor) AS ClienteCedula,
       concat(d.nombres, ':', planilla.fuerza, ':', planilla.cuotas, ':', d.libranza, ':', planilla.promotor) AS ClienteNombre,
      d.valor, d.tipo, concat(d.ano, '/', d.mes, '-', left(d.tipo,3)) AS anoMes,
      planilla.fuerza, planilla.cuotas, planilla.promotor
FROM cartera d INNER JOIN
     cartera x
     ON d.cedula = x.cedula INNER JOIN
     cartera y
     ON d.cedula = y.cedula INNER JOIN
     planilla
     ON d.libranza = planilla.libranza
WHERE (d.tipo not like '%RI-%') AND (left(x.tipo, 3) like 'RC-')
GROUP BY d.idcartera, d.cedula;

您执行了三次自连接,没有引用y表,并且执行了没有聚合功能的聚合。

第一个简化是一起删除y 我认为过滤需要用到x的联接,所以我将其替换为一个exists 而且,我猜测最终查询不需要这些简化的汇总。 因此,也许这就是您想要的:

SELECT d.idcartera,
       concat(d.cedula, ':', p.fuerza, ':', p.cuotas, ':', d.libranza, ':',   p.promotor) AS ClienteCedula,
       concat(d.nombres, ':', p.fuerza, ':', p.cuotas, ':', d.libranza, ':', p.promotor) AS ClienteNombre,
      d.valor, d.tipo, concat(d.ano, '/', d.mes, '-', left(d.tipo,3)) AS anoMes,
      p.fuerza, p.cuotas, p.promotor
FROM cartera d INNER JOIN
     planilla p
     ON d.libranza = p.libranza
WHERE d.tipo not like '%RI-%' AND
      exists (select 1
              from cartera x
              where d.cedula = x.cedula and
                    x.tipo like 'RC-%'
             );

如果这会产生许多重复项,则可能仍要包括select distinct different。

我假设您在join键(特别是planilla(libranza) )上有索引。 您还需要在cartera(cedula, tipo)cartera(cedula, tipo)索引。 不幸的是,由于初始通配符的原因,表达式d.tipo not like '%RI-%'那样无法使用索引。 如果为此需要性能,则可能需要考虑在字段上使用全文本索引。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM