SQL查询执行缓慢

时间:2016-07-04 19:59:16

标签: mysql

我有一个SQL查询的问题,它给了我想要的输出,并且在我的计算机上工作正常,但由于我必须在学校的PC上运行我的数据库,我遇到了问题。查询需要34个!要执行的秒数,而在我的电脑上它需要像6。

这是我的DB:

enter image description here

查询是:你必须为每个健身成员的用户找到练习“Panca Orizzontale”,“Squat”,“Estensioni Bilanciere”,“Squat”的1 rep max(Max(Carico))超过5年。

这是我正在使用的查询:

SELECT U.Nome
     , U.Cognome
     , MAX(P1.Carico) AS MaxPanca_Orizzontale
     , MAX(P2.Carico) AS MaxSquat
     , MAX(P3.Carico) AS MaxEstensioni_Bilanciere
     , MAX(P4.Carico) AS MaxLento_Avanti
  FROM utente AS U 
  left 
  join scheda AS S1 
    on U.CF=S1.ID_Utente 
  left 
  join programma AS P1 
    on S1.ID_Scheda = P1.ID_Scheda 
   AND P1.nRipetizioni = 1 
   AND P1.Esercizio = "Panca Orizzontale"
  left 
  join scheda AS S2 
    on U.CF=S2.ID_Utente 
  left 
  join programma AS P2 
    on S2.ID_Scheda = P2.ID_Scheda 
   AND P2.nRipetizioni = 1 
   AND P2.Esercizio = "Squat"
  left 
  join scheda AS S3 
    on U.CF = S3.ID_Utente 
  left 
  join programma AS P3 
    on S3.ID_Scheda = P3.ID_Scheda 
   AND P3.nRipetizioni = 1 
   AND P3.Esercizio = "Estensioni Bilanciere"
  left 
  join scheda AS S4 
    on U.CF = S4.ID_Utente 
  left 
  join programma AS P4 
    on S4.ID_Scheda = P4.ID_Scheda 
   AND P4.nRipetizioni = 1 
   AND P4.Esercizio = "Lento Avanti"
 WHERE U.CF IN(SELECT U.CF 
                 FROM utente U 
                WHERE Data_Iscrizione < date_sub(curdate(), interval 5 year)
              )
 GROUP 
    BY U.Nome
     , U.Cognome;

这是理想的结果:

enter image description here

可能所有这些加入都是问题,有没有办法让它更快执行?谢谢你的时间

2 个答案:

答案 0 :(得分:0)

我声明您最好将programma.Esercizio添加到群组中。 类似的东西:

SELECT U.Nome, U.Cognome, P.Esercizio, MAX(Carico) AS MaxCarico
FROM utente AS U left join scheda AS S1 on U.CF=S1.ID_Utente 
left join programma AS P1 on S1.ID_Scheda=P1.ID_Scheda AND P1.nRipetizioni=1
WHERE U.CF IN(SELECT U.CF FROM utente U WHERE Data_Iscrizione < date_sub(curdate(), interval 5 year))
GROUP BY U.Nome, U.Cognome, P.Esercizio;

输出会有点不同(额外的列和4行而不是ne),但是对于数据库服务器来说,处理起来要好得多。你能测试一下,看看它是否仍然符合你的需求吗?

答案 1 :(得分:0)

我现在已经改变了我的答案并用你的数据写了新的。

首先你必须创建2个新索引

ALTER TABLE programma
ADD KEY `idx_nRipetizioni` (`nRipetizioni`,`ID_Scheda`,`Esercizio`);

ALTER TABLE utente
ADD KEY `idx_ata_Iscrizione` (`Data_Iscrizione`);

然后你可以运行它。请测试一下结果是一样的。 如果你想要NULL而不是0改变,0)改为,NULL) 在if语句中

并查看执行时间: - )

SELECT 
  U.Nome,
  U.Cognome,
  MAX(IF(P1.Esercizio="Panca Orizzontale",P1.Carico,0)) AS MaxPanca_Orizzontale,
  MAX(IF(P1.Esercizio="Squat",P1.Carico,0)) AS MaxSquat,
  MAX(IF(P1.Esercizio="Estensioni Bilanciere",P1.Carico,0)) AS MaxEstensioni_Bilanciere,
  MAX(IF(P1.Esercizio="Lento Avanti",P1.Carico,0)) AS MaxLento_Avanti
FROM utente AS U
LEFT JOIN scheda AS S1 ON U.CF=S1.ID_Utente
LEFT JOIN programma AS P1 ON S1.ID_Scheda=P1.ID_Scheda
          AND P1.nRipetizioni=1
WHERE Data_Iscrizione < date_sub(curdate(), INTERVAL 5 YEAR)
GROUP BY U.Nome,
         U.Cognome;

<强>样品

创建索引

MariaDB [yourschema]> ALTER TABLE programma
    -> ADD KEY `idx_nRipetizioni` (`nRipetizioni`,`ID_Scheda`,`Esercizio`);

Query OK, 0 rows affected (0.27 sec)
Records: 0  Duplicates: 0  Warnings: 0

创建索引

MariaDB [yourschema]> ALTER TABLE utente
    -> ADD KEY `idx_ata_Iscrizione` (`Data_Iscrizione`);
Query OK, 0 rows affected, 1 warning (0.08 sec)
Records: 0  Duplicates: 0  Warnings: 1

运行查询

MariaDB [yourschema]> SELECT
    ->   U.Nome,
    ->   U.Cognome,
    ->   MAX(IF(P1.Esercizio="Panca Orizzontale",P1.Carico,0)) AS MaxPanca_Orizzontale,
    ->   MAX(IF(P1.Esercizio="Squat",P1.Carico,0)) AS MaxSquat,
    ->   MAX(IF(P1.Esercizio="Estensioni Bilanciere",P1.Carico,0)) AS MaxEstensioni_Bilanciere,
    ->   MAX(IF(P1.Esercizio="Lento Avanti",P1.Carico,0)) AS MaxLento_Avanti
    -> FROM utente AS U
    -> LEFT JOIN scheda AS S1 ON U.CF=S1.ID_Utente
    -> LEFT JOIN programma AS P1 ON S1.ID_Scheda=P1.ID_Scheda
    ->           AND P1.nRipetizioni=1
    -> WHERE Data_Iscrizione < date_sub(curdate(), INTERVAL 5 YEAR)
    -> GROUP BY U.Nome,
    ->          U.Cognome;
+------------+--------------+----------------------+----------+--------------------------+-----------------+
| Nome       | Cognome      | MaxPanca_Orizzontale | MaxSquat | MaxEstensioni_Bilanciere | MaxLento_Avanti |
+------------+--------------+----------------------+----------+--------------------------+-----------------+
| Ajeje      | Brazov       |                  0.0 |    100.0 |                      0.0 |            35.0 |
| Aldo       | Baglio       |                 80.0 |    120.0 |                     32.5 |            50.0 |
| Fernando   | Torres       |                  0.0 |    150.0 |                      0.0 |            35.0 |
| Francesco  | Toldo        |                 90.0 |      0.0 |                     40.0 |             0.0 |
| Giovanni   | Storti       |                 65.0 |      0.0 |                      0.0 |            30.0 |
| Guendalina | Porte        |                  0.0 |     50.0 |                     20.0 |            25.0 |
| Harry      | Potter       |                150.0 |    180.0 |                     80.0 |           122.5 |
| John       | Cena         |                135.0 |    240.0 |                     60.0 |            75.5 |
| Kevin      | Velociraptor |                  0.0 |      0.0 |                     20.0 |            95.0 |
| Luciano    | Spalletti    |                 60.0 |    280.0 |                     95.0 |           100.0 |
| Marcella   | Mandria      |                  0.0 |     50.0 |                      0.0 |            27.5 |
| Marcelo    | Zalayeta     |                140.0 |    200.0 |                     55.0 |            60.0 |
| Radja      | Nainggolan   |                 90.0 |    120.0 |                      0.0 |            40.0 |
| Romina     | Power        |                  0.0 |      0.0 |                    140.0 |            20.0 |
+------------+--------------+----------------------+----------+--------------------------+-----------------+
14 rows in set (0.00 sec)

MariaDB [yourschema]>