Bonjour,
j'ai une certain requête, assez longue (et ce n'est que la sous requête d'une autre) mais que j'ai fait le plus compréhensible possible ....
Je ne vais pas m'attarder plus, la voici :
bon, c'est très bien, mais j'ai néanmoins remarqué que si au lieu de retourner tout au lieu de juste un champs, ça ne prenais que 100 ms. Avec cette requête qui renvoie tous les résultats, ça prend 700 ms.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 SELECT * FROM(SELECT *, seances.id AS id_seance, activities.id AS id_activity, MAX(nb_real) OVER(PARTITION BY realisations.seance) AS nb_real_max,modules.cycle AS module_cycle, seances.repetition AS module_repetition, modules.id AS id_mod, ROW_NUMBER() OVER(PARTITION BY modules.id ORDER BY realisations.nb_real ASC, ordre ASC) AS rn FROM modules INNER JOIN activities ON activities.id_module = modules.id INNER JOIN seances ON seances.id_module=modules.id INNER JOIN j_seances_niveaux js ON js.id_seance=seances.id AND id_niveau = 11 INNER JOIN j_membres_modules jm ON jm.membre = 1 AND jm.module = modules.id LEFT JOIN realisations ON realisations.activity = activities.id AND member = 1 LEFT JOIN provocations ON provocations.provoque = activities.id WHERE (activities.type_freq=3 OR activities.type_freq=1) -- filtre de la fréquence AND (modules.cycle='1' OR (date_start<NOW() AND date_end < NOW())) -- filtre pour la date ... AND (jm.report IS NULL OR jm.report <= NOW()) -- en faisant attention aux reports éventuels ) AS tmp WHERE rn = 1 AND (tmp.module_cycle='1' OR nb_real_max IS NULL OR nb_real_max < tmp.module_repetition) -- filtre pour la répétition
Alors, j'ai eu une idée : au lieu de tout retourner, pourquoi ne pas retourner seulement quelques champs, et faire ensuite des INNER JOIN pour récupérer les même données ? Et ça donne ceci :
temps d'exécution : ... 150 ms !!!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 SELECT * FROM(SELECT seances.id AS id_seance, activities.id AS id_activity, MAX(nb_real) OVER(PARTITION BY realisations.seance) AS nb_real_max,modules.cycle, seances.repetition, modules.id AS id_mod, ROW_NUMBER() OVER(PARTITION BY modules.id ORDER BY realisations.nb_real ASC, ordre ASC) AS rn FROM modules INNER JOIN activities ON activities.id_module = modules.id INNER JOIN seances ON seances.id_module=modules.id INNER JOIN j_seances_niveaux js ON js.id_seance=seances.id AND id_niveau = 11 INNER JOIN j_membres_modules jm ON jm.membre = 1 AND jm.module = modules.id LEFT JOIN realisations ON realisations.activity = activities.id AND member = 1 LEFT JOIN provocations ON provocations.provoque = activities.id WHERE (activities.type_freq=3 OR activities.type_freq=1) -- filtre de la fréquence AND (modules.cycle='1' OR (date_start<NOW() AND date_end < NOW())) -- filtre pour la date ... AND (jm.report IS NULL OR jm.report <= NOW()) -- en faisant attention aux reports éventuels ) AS tmp INNER JOIN modules ON modules.id = tmp.id_mod INNER JOIN activities ON activities.id = id_activity INNER JOIN seances ON seances.id = id_seance WHERE rn = 1 AND (tmp.cycle='1' OR nb_real_max IS NULL OR nb_real_max < tmp.repetition) -- filtre pour la répétition
En fait, je ne m'y attendais pas
au fait, à quoi c'est dû ? je crois deviner à moitié, mais sans plus .... Je suppose que au plus la masse de données à traiter dans les fonction analytique sont faibles, au plus c'est rapide, même si toutes les données ne joue pas dans ces fonctions analytique ... Je me trompe ?
Et sinon, verriez-vous d'autre amélioration à apporter ?
Quelque infos qui pourrais servir :
les tables les plus lourde sont :
seance (~ 20 000 lignes)
realisations (très lourde, de 5 000 à 1 000 000 de lignes, et environ 10 000 pour un même membre (cf champ realisations.member))
Merci d'avance.
PS
Peut-être avez vous remarqué que dans la deuxième requête, je ne récupère pas les résultats des tables provocations et realisations, mais même si je les récupère, ça fait en tout 160 ms, presque rien quoi.
Partager