Optimisation d'une requête SVP

Fermé
ko3ar Messages postés 8 Date d'inscription jeudi 13 septembre 2012 Statut Membre Dernière intervention 26 janvier 2015 - Modifié par jordane45 le 22/01/2015 à 13:35
ko3ar Messages postés 8 Date d'inscription jeudi 13 septembre 2012 Statut Membre Dernière intervention 26 janvier 2015 - 26 janv. 2015 à 19:27
Bonjour,

J'ai une requête qui mets bcp de temps, je n'arrive vraiment pas à l'optimiser.

Deux table sont concernées, Membere + Tchat message

Le but est de recevoir toutes les lignes du tchat avec le pseudo de chaque membre sur le côté, pour ce faire, y a plusieurs requetes, mais la plus importante est celle ci :
$sql = "SELECT * FROM (
      SELECT DISTINCT t2.pseudo, t2.id as id, t1.send FROM `chat_messages` t1,         `member` t2
      WHERE
      (
         (t1.`sender_id` = ".$_POST['user']." AND t1.`status` != 1 AND t1.`receiver_id` = t2.`id`)
           OR
         (t1.`receiver_id` = ".$_POST['user']." AND t1.`status` != 2 AND t1.`sender_id` = t2.`id`)
      )
   ORDER BY t1.`send` desc) C GROUP BY `pseudo` ORDER BY send DESC";

$request = mysql_query($sql);


Je ne sais pas si vous pouvez m'aider sans connaitre le besoin, mais au moins si vous avez une idée de jointure par exemple qui peut oprimiser ;)

Merci bcp par avance de votre aide.

Au plaisir de vous lire.

Cdt



EDIT : Ajout des balilses de code

A voir également:

3 réponses

Reivax962 Messages postés 3671 Date d'inscription jeudi 16 juin 2005 Statut Membre Dernière intervention 11 février 2021 1 011
22 janv. 2015 à 12:53
Bonjour,

As-tu défini des index sur chat_message ?
À mon avis c'est la première étape.
Un index sur chat_message.sender_id, et un sur chat_message.receiver_id.

Par ailleurs, je ne suis pas sûr de comprendre l'intérêt de ton GROUP BY sachant qu'il n'y a aucune fonction d'agrégation dans ton résultat.

Tu peux montrer un exemple du résultat que tu attends ?

Xavier
0
jordane45 Messages postés 38145 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 25 avril 2024 4 650
Modifié par jordane45 le 22/01/2015 à 13:46
Bonjour,

Plusieurs petites choses...
- Tu injectes directement une variable POST ... sans avoir au préalable vérifier qu'elle existait.
- Je pense qu' une jointure serait plus adaptée ....

N'ayant pas la structure de tes tables je ne peux pas tester.. .mais quelque chose de ce genre devrait faire l'affaire.
$user = isset($_POST['user'])?$_POST['user']:NULL;
if($user){
$sql = "SELECT DISTINCT M.pseudo
                , M.id as id
                , CM.send 
        FROM `chat_messages` CM
        LEFT JOIN `member` M ON ((M.id=CM.sender_id OR M.id=CM.receiver_id) AND CM.`status` != 1)
        GROUP BY pseudo 
        ORDER BY send DESC";

$request = mysql_query($sql) or die("erreur !<br>".$sql);


}



Cordialement,
Jordane
0
ko3ar Messages postés 8 Date d'inscription jeudi 13 septembre 2012 Statut Membre Dernière intervention 26 janvier 2015 5
Modifié par jordane45 le 22/01/2015 à 19:18
Bonjour à vous et merci pour votre aide,
Tout d'abord, pour les index sur chat_message.sender_id, et un sur chat_message.receiver_id. c'est déjà fait.

Le group by c'est pour regrouper en fonction des dates les plus recentes (send est un champ date)

Voici ci joint le réssultat attendu



Jordane, merci bcp, voici la structure des deux tables:

chat_message:
CREATE TABLE IF NOT EXISTS `chat_messages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `sender_id` int(11) NOT NULL,
  `receiver_id` int(11) NOT NULL,
  `message` text COLLATE utf8_unicode_ci NOT NULL,
  `send` datetime NOT NULL,
  `read` int(11) NOT NULL,
  `status` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `IDX_received` (`receiver_id`),
  KEY `IDX_sender` (`sender_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=303054 ;


et pour membre
CREATE TABLE IF NOT EXISTS `member` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `pseudo` varchar(15) COLLATE latin1_general_ci NOT NULL DEFAULT '',
  `first_name` varchar(255) COLLATE latin1_general_ci NOT NULL DEFAULT '',
  `last_name` varchar(255) COLLATE latin1_general_ci NOT NULL DEFAULT '',
  `email` varchar(255) COLLATE latin1_general_ci NOT NULL DEFAULT '',
  `temp_email` varchar(255) COLLATE latin1_general_ci DEFAULT NULL,
  `password` varchar(40) COLLATE latin1_general_ci NOT NULL,
   `postcode` varchar(10) COLLATE latin1_general_ci NOT NULL DEFAULT '',
  `city` varchar(255) COLLATE latin1_general_ci NOT NULL DEFAULT '',
  `country` int(11) unsigned DEFAULT NULL,
  `region` int(11) unsigned DEFAULT NULL,
  `department` int(11) unsigned DEFAULT NULL,
    `type` tinyint(4) unsigned NOT NULL DEFAULT '0',
  `date_of_birth` date NOT NULL DEFAULT '0000-00-00',
  `birth_sign` int(11) DEFAULT NULL,
  `my_search` int(11) unsigned NOT NULL DEFAULT '0',
  `type_of_meeting` varchar(45) COLLATE latin1_general_ci NOT NULL DEFAULT '',
  
  PRIMARY KEY (`id`),
  UNIQUE KEY `uniic_member_pseudo` (`pseudo`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci AUTO_INCREMENT=21959 ;



je suis d'accord, je pense qu'il faudrait une jointure mais je suis bloqué j'arrive plus :(

Merci énormément de votre aide

EDIT : Ajout des balises de code
0
jordane45 Messages postés 38145 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 25 avril 2024 4 650
22 janv. 2015 à 19:19
Tu as testé ma requête ?

Par contre... testes là en direct dans ta BDD ... pas via le php !
Je t'invite à lire ceci :
https://codes-sources.commentcamarche.net/faq/10778-heidisql-tester-ses-requetes-sql


.
0
ko3ar Messages postés 8 Date d'inscription jeudi 13 septembre 2012 Statut Membre Dernière intervention 26 janvier 2015 5
Modifié par ko3ar le 22/01/2015 à 20:13
jordane, oui je l'ai modifié en ajoutant la partie status et pour le moment, ta requête fait bcp de bien :), je l'utilise du coup en attendant optimiser encore plus si possible, sinon je la garde :):)

Merci bcp Jordane, tu m'a rendu un grand service :)
0
jordane45 Messages postés 38145 Date d'inscription mercredi 22 octobre 2003 Statut Modérateur Dernière intervention 25 avril 2024 4 650 > ko3ar Messages postés 8 Date d'inscription jeudi 13 septembre 2012 Statut Membre Dernière intervention 26 janvier 2015
22 janv. 2015 à 20:54
Ben la. .. je ne vois pas comment tu pourrais plus l'optimiser. ..
0
ko3ar Messages postés 8 Date d'inscription jeudi 13 septembre 2012 Statut Membre Dernière intervention 26 janvier 2015 5
Modifié par ko3ar le 26/01/2015 à 19:27
Bonjour Jordane45
En fait, c'est vrai qu'on peut pas faire mieux, mais ce qu'il me gène un peu, c'est que quand je mets un Explain, j'ai ce message :
Range checked for each record (index map: 0x1)

et j'ai vu que ce n'est pas top en terme de performance
vous en pensez quoi ?

Merci beaucoup de votre conseil
0