Partage
  • Partager sur Facebook
  • Partager sur Twitter

Performance requête imbriquée catastrophique !

Copying to tmp table, 30 secondes de traitement

25 avril 2011 à 15:42:47

Bonjour,

J'ai une requête composée qui prend anormalement beaucoup de temps :

SELECT user_id, username, user_type, user_posts
FROM phpbb_users
WHERE user_id IN(
	SELECT DISTINCT topic_poster AS user_id
	FROM phpbb_topics
	WHERE forum_id = 33
)
-- Affichage des enregistrements 0 - 29 (57 total, Traitement en 23.9452 sec.)


Alors j'ai testé les deux requêtes séparément, et là elles s'exécutent normalement (très rapide) :


/*
 * Requête principale
 */
SELECT user_id, username, user_type, user_posts
FROM phpbb_users
WHERE user_id IN(
	1622, 1668, 1691, 1701, 1720, 1696, 1767, 1763, 1822, 1855, 1889, 1874,
	1908, 1916, 1920, 1925, 1909, 1955, 1956, 1975, 1991, 2576, 2671, 2667,
	2668, 2713, 2724, 2726, 2738, 2740, 2750, 2751, 2755, 2758, 2759, 2753,
	2771, 2772, 2773, 2775, 2782, 2813, 2848, 2851, 2868, 2879, 2899, 2814,
	2910, 2922, 2909, 2897, 2709, 2893, 2933, 2754, 2923
)
-- Affichage des enregistrements 0 - 29 (57 total, Traitement en 0.0008 sec.)


/*
 * Sous-requête
 */
SELECT DISTINCT topic_poster AS user_id
FROM phpbb_topics
WHERE forum_id = 33
-- Affichage des enregistrements 0 - 29 (57 total, Traitement en 0.0015 sec.)



Ensuite j'ai lancé un profilage de cette requête, et ça crache de partout, je vois plein de "Copying to tmp table", vous pouvez voir tout le profilage ici.

Comment faire pour corriger ce problème (j'ai essayé au lance requête comme dans les films, mais ça ne fonctionne pas du tout :-° ) ?

Merci
  • Partager sur Facebook
  • Partager sur Twitter
25 avril 2011 à 18:54:29

Essaie

SELECT user_id, username, user_type, user_posts
FROM phpbb_users
     inner join (SELECT DISTINCT topic_poster AS user_id
  	         FROM phpbb_topics
	         WHERE forum_id = 33) x
            on x.user_id = phpbb_users.user_id


Cela ne ferait pas de différence avec Oracle ou SQL Server, mais l'optimiseur de requêtes de MySQL a parfois des faiblesses. Alternativement, si je me trompe, il y a la sous-requête correlée

SELECT user_id, username, user_type, user_posts
FROM phpbb_users
where exists (SELECT null
  	      FROM phpbb_topics
	      WHERE forum_id = 33
               and topic_poster = phpbb_users.user_id)



  • Partager sur Facebook
  • Partager sur Twitter
25 avril 2011 à 19:12:40

Merci, ta première requête fonctionne :
Affichage des enregistrements 0 - 29 (57 total, Traitement en 0.0113 sec.)

Il faut juste modifier la clause select pour pas avoir cette erreur : #1052 - Champ: 'user_id' dans field list est ambigu.

Par contre la seconde est encore plus lente que l'originale. Merci pour ton aide, je vais quand même faire quelques tests pour comprendre pourquoi une requête aussi simple pose ces problèmes (en essayant avec/sans index, et avec plusieurs moteurs différents).
  • Partager sur Facebook
  • Partager sur Twitter