如何优化这个查询MySQL

时间:2014-09-08 17:19:17

标签: mysql sql

我有这个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"表是过滤一些数据

2 个答案:

答案 0 :(得分:0)

对于查询的第一部分(查询和分组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可以应用于索引列tipo。

对于x和y的连接,你应该添加以下索引(如果它还不是PK):

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

对于planilla的加入,请添加     在Planilla(liberanza)上创建INDIN i3(如果还没有PK)

答案 1 :(得分:0)

以下是您的查询:

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

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

相关问题