如何优化 mysql 查询

Posted

技术标签:

【中文标题】如何优化 mysql 查询【英文标题】:How to optimize a mysql query 【发布时间】:2019-03-14 21:31:21 【问题描述】:

我有一个 mysql 查询的问题,有时需要 80 多秒才能执行。

你能帮我优化一下吗?

这里是我的sql代码

SELECT
 codFinAtl,
 nome,
 cognome,
 dataNascita AS annoNascita,
 MIN(tempoRisultato) AS tempoRisultato
FROM
graduatorie
INNER JOIN anagrafica ON codFin = codFinAtl
INNER JOIN manifestazionigrad ON manifestazionigrad.codice = graduatorie.codMan
WHERE
 anagrafica.eliminato = 'n' 
 AND graduatorie.eliminato = 'n' 
 AND codGara IN('01', '81') 
 AND sesso = 'F' 
 AND manifestazionigrad.aa = '2018/19' 
 AND graduatorie.baseVasca = '25' 
 AND tempoRisultato IS NOT NULL 
 AND dataNascita BETWEEN '20050101' AND '20061231'
GROUP BY
 codFinAtl
ORDER BY
 tempoRisultato,
 cognome,
 nome

还有我的数据库架构

[更新]

这里是EXPLAIN查询的结果

+----+-------------+--------------------+------------+--------+--------------------------+-----------+---------+-------------------------------+--------+----------+----------------------------------------------+
| id | select_type | table              | partitions | type   | possible_keys            | key       | key_len | ref                           | rows   | filtered | Extra                                        |
+----+-------------+--------------------+------------+--------+--------------------------+-----------+---------+-------------------------------+--------+----------+----------------------------------------------+
|  1 | SIMPLE      | anagrafica         | NULL       | ALL    | codFin                   | NULL      | NULL    | NULL                          | 334094 |     0.11 | Using where; Using temporary; Using filesort |
|  1 | SIMPLE      | graduatorie        | NULL       | ref    | codMan,codFinAtl,codGara | codFinAtl | 33      | finsicilia.anagrafica.codFin  |     20 |     0.24 | Using where                                  |
|  1 | SIMPLE      | manifestazionigrad | NULL       | eq_ref | codice                   | codice    | 32      | finsicilia.graduatorie.codMan |      1 |    10.00 | Using index condition; Using where           |
+----+-------------+--------------------+------------+--------+--------------------------+-----------+---------+-------------------------------+--------+----------+----------------------------------------------+

【问题讨论】:

另外,关于查询优化的问题总是需要给定查询的解释 为什么 'manifestazionigrad.codice' 获得了资格,没有别的? :-( ? 我们需要查看索引;请提供SHOW CREATE TABLE。该查询读起来很笨拙,因为某些列不符合它们所在的表。您听说过“复合索引”吗? @Strawberry 我添加了解释结果 感谢进度报告 【参考方案1】:
graduatorie:  INDEX(eliminato, baseVasca)
manifestazionigrad:  INDEX(aa, codMan)

这些可能还不够。请限定查询中的每一列,以便我们知道它们来自哪个表。

但真正的问题可能是“explode-implode”。首先它在JOINing 处爆炸,然后在GROUP BY 处内爆。

是否可以计算MIN(tempoRisultato)没有任何JOINs? (我什至不知道涉及哪张桌子。)如果是这样,请提供,然后我们可以讨论下一步该做什么。可能有两种选择:带有MIN 的派生表,或JOIN 中可能相关或不相关的子查询。

tempoRisultato 似乎在两个表中!)

【讨论】:

以上是关于如何优化 mysql 查询的主要内容,如果未能解决你的问题,请参考以下文章

mysql如何优化以下语句,查询耗时太久了?

如何优化 mysql 查询

如何优化 mysql 查询

如何在 mysql 查询下进行优化(我是优化新手)

如何迭代优化 MySQL 查询?

如何优化Mysql千万级快速分页