如何改进查询Mysql?

时间:2014-03-21 13:25:54

标签: mysql performance

我在MySql中进行了此查询。它找到但查询的时间是3或+分钟。

我想知道是否可以改进此查询。

查询是这样的:

SELECT CODARTIOLO, NOMEARTICOLO, SUM(QUANTITA) AS QUANTITA,
  (SUM(TOTRIGA)/SUM(QUANTITA)) AS TOTALE,
  (SELECT (SUM(QUANTITA * PREZZOCAD))/SUM(QUANTITA)
   FROM vistacaricomagazzino cm
   WHERE cm.DATA <= '$dataStart' AND cm.codarticolo=CODARTIOLO) AS PREZZOMEDIO 
FROM vistascontrini c 
WHERE c.DATA >= '$dataStart' AND c.DATA <= '$dataEnd'
GROUP BY NOMEARTICOLO

表格是:

VISTASCONTRINI

+--------------+--------------+------+-----+------------+-------+
| Field        | Type         | Null | Key | Default    | Extra |
+--------------+--------------+------+-----+------------+-------+
| CODARTIOLO   | varchar(13)  | YES  |     | NULL       |       |
| NOMEARTICOLO | varchar(60)  | YES  |     | NULL       |       |
| QUANTITA     | int(11)      | YES  |     | NULL       |       |
| TOTRIGA      | decimal(9,2) | YES  |     | NULL       |       |
| DATA         | date         | NO   |     | 0000-00-00 |       |

VISTACARICOMAGAZZINO

+-------------+---------------+------+-----+---------+-------+
| Field       | Type          | Null | Key | Default | Extra |
+-------------+---------------+------+-----+---------+-------+
| codordine   | int(11)       | NO   |     | 0       |       |
| Quantita    | int(11)       | YES  |     | NULL    |       |
| PrezzoCad   | decimal(10,3) | YES  |     | NULL    |       |
| codArticolo | varchar(13)   | YES  |     | NULL    |       |
| Data        | date          | YES  |     | NULL    |       |
+-------------+---------------+------+-----+---------+-------+

3 个答案:

答案 0 :(得分:0)

如果你的表没有索引(并且它们看起来不像那样),那么这是你需要修复的第一件事。如果你这样做(即将索引放在需要索引的字段上),它可能会在一次点击中为你解决问题。

您需要考虑索引的字段是WHERE和GROUP BY子句使用的字段。

接下来,考虑将它从嵌套的SELECT查询转换为JOIN查询。这也可能会给你带来更好的表现。

最后,你还没有说明这里要整理多少数据,但是如果它是大量数据,那么考虑将整理的数据总数分别存储在数据库中,这样你就可以直接查询它而不是每次重新生成所有这些总和和组。这显然有它自己的考虑因素(额外的存储,更新数据时的额外代码也会更新总数,事情不同步的可能性等),但如果你真的在这方面遇到了性能,那么这是一个有效的解决方案。

答案 1 :(得分:0)

我认为您可以尝试从select子句中删除子查询。将查询修改为(未经测试,只是为了获得想法)

SELECT c.CODARTIOLO,c.NOMEARTICOLO,SUM(c.QUANTITA) AS QUANTITA,(SUM(c.TOTRIGA)/SUM(c.QUANTITA)) AS TOTALE,(SUM(cm.QUANTITA * cm.PREZZOCAD))/SUM(cm.QUANTITA) 
FROM vistascontrini c,
vistacaricomagazzino cm
WHERE  cm.codarticolo=c.CODARTIOLO
AND cm.DATA <= '$dataStart'
AND c.DATA >= '$dataStart' AND c.DATA <= '$dataEnd' group by NOMEARTICOLO

同时在表DATAvistascontrini的{​​{1}}列添加索引。

答案 2 :(得分:0)

vistascontrini.DATA, vistascontrini.NOMEARTICOLO, vistacaricomagazzino.DATA, vistacaricomagazzino.codarticolo

上添加索引

目前尚不清楚您是否希望按CODARTIOLO进行分组,如果您的论坛只有NOMEARTICOLO,您还需要什么价值?

尝试使用以下等同于您的查询:

SELECT T.*,T1.PREZZOMEDIO FROM
(
   SELECT CODARTIOLO,NOMEARTICOLO,
          SUM(QUANTITA) AS QUANTITA,
          (SUM(TOTRIGA)/SUM(QUANTITA)) AS TOTALE,
     FROM vistascontrini c 
          WHERE  c.DATA >= '$dataStart' AND c.DATA <= '$dataEnd' 
     group by NOMEARTICOLO
) AS T
LEFT JOIN 
   ( SELECT CODARTIOLO,(SUM(QUANTITA * PREZZOCAD))/SUM(QUANTITA) as PREZZOMEDIO 
            FROM vistacaricomagazzino cm 
            WHERE cm.DATA <= '$dataStart' 
     GROUP BY CODARTIOLO ) as T1
ON T.CODARTIOLO=T1.CODARTIOLO