[英]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.