Optimisation d'une requête SVP

ko3ar Messages postés 8 Date d'inscription   Statut Membre Dernière intervention   -  
ko3ar Messages postés 8 Date d'inscription   Statut Membre Dernière intervention   -
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

3 réponses

Reivax962 Messages postés 3672 Date d'inscription   Statut Membre Dernière intervention   1 011
 
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 38486 Date d'inscription   Statut Modérateur Dernière intervention   4 752
 
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   Statut Membre Dernière intervention   5
 
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 38486 Date d'inscription   Statut Modérateur Dernière intervention   4 752
 
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   Statut Membre Dernière intervention   5
 
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 38486 Date d'inscription   Statut Modérateur Dernière intervention   4 752 > ko3ar Messages postés 8 Date d'inscription   Statut Membre Dernière intervention  
 
Ben la. .. je ne vois pas comment tu pourrais plus l'optimiser. ..
0
ko3ar Messages postés 8 Date d'inscription   Statut Membre Dernière intervention   5
 
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