2011-04-26 4 views
1

Au fur et à mesure que ma base de données de messages privés a commencé à croître, je remarque des ralentissements considérables sur la requête suivante.MySQL Query ralenti lors de l'utilisation de l'opérateur OU

la requête:

SELECT * FROM privatemessages WHERE sender='940' OR recipient='940' ORDER BY id DESC LIMIT 1000; 

(L 940 peut être l'un quelconque code d'utilisateur)

Le Tableau:

CREATE TABLE `privatemessages` (
    `id` int(11) NOT NULL auto_increment, 
    `recipient` int(11) NOT NULL, 
    `sender` int(11) NOT NULL, 
    `time` int(11) NOT NULL, 
    `readstatus` int(11) NOT NULL, 
    `message` varchar(255) NOT NULL, 
    `messagetype` int(11) NOT NULL, 
    `rdeleted` int(11) NOT NULL, 
    `sdeleted` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    KEY `recipient` (`recipient`), 
    KEY `sender` (`sender`), 
    KEY `read` (`readstatus`), 
    KEY `time` (`time`), 
    KEY `openmessagingpanel` (`recipient`,`readstatus`), 
    KEY `openpmthreadrev` (`recipient`,`sender`), 
    KEY `openpmthread` (`sender`,`recipient`) 
) ENGINE=InnoDB AUTO_INCREMENT=8650153 DEFAULT CHARSET=latin1 

MySQL explique:

+----+-------------+-----------------+-------------+------------------------------------------------------------------+------------------+---------+------+-------+--------------------------------------------+ 
| id | select_type | table   | type  | possible_keys             | key    | key_len | ref | rows | Extra          | 
+----+-------------+-----------------+-------------+------------------------------------------------------------------+------------------+---------+------+-------+--------------------------------------------+ 
| 1 | SIMPLE  | privatemessages | index_merge | recipient,sender,openmessagingpanel,openpmthreadrev,openpmthread | sender,recipient | 4,4  | NULL | 26100 | Using union(sender,recipient); Using where | 
+----+-------------+-----------------+-------------+------------------------------------------------------------------+------------------+---------+------+-------+--------------------------------------------+ 
1 row in set (0.00 sec) 

Est-ce que quelqu'un sait ce que je dois faire pour obtenir cette requête de retour à la vitesse? Il y a environ 8 millions d'enregistrements.

Merci.

+0

Avez-vous vraiment besoin d'aller chercher tous les champs pour les lignes que vous avez trouvées ('SELECT *')? –

+0

Avez-vous défini un autre index sur cette table qui est combiné pour l'expéditeur et le destinataire? Quand je prends juste votre définition de table, j'obtiens un plan d'explication beaucoup plus propre: – Wes

+0

Désolé, j'avais foiré ma copie et les coller. Le message original a été corrigé en fonction de la base de données, même s'il est assez compliqué de tester certaines choses plus tôt aujourd'hui. – Brian

Répondre

0

2 pensées:

  • Est-il utile de créer une vue pour les messages ayant un statut non effacé, et la sélection des messages à partir de là, en supposant qu'il y aura moins de CERs à traiter.
  • verbeux à propos de SELECT-ment les champs dont vous avez besoin donne habituellement un gain de performance
0

Vous avez allready un index sur la colonne de l'émetteur et le récepteur.

En supposant que vous avez besoin de la demande de l'interface graphique où l'utilisateur peut sélectionner un message à lire:

Si vous ne sélectionnez id, titre et peut-être le temps que ce serait assez pour afficher les liens vers les messages. De même, vous pouvez définir une limite à 50 ou plus et faire une certaine pageination.

ou avez-vous besoin pour l'exportation? alors vous devriez plutôt utiliser la fonctionnalité d'exportation de mysql ...

espérons que cela vous aide.