如何优化 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 查询的主要内容,如果未能解决你的问题,请参考以下文章