2010-11-20 6 views
0

J'ai une grande table mysql (environ 5M lignes) sur laquelle j'insère fréquemment des données.Mysql concurrent sélectionner et insérer ralentir la base de données

Cette table est la même que je dois lire des données et parfois la base de données entière devient lente à cause de la sélection de données alors qu'il y a beaucoup d'insertions en attente. J'ai mis des index sur chaque champ que j'utilise dans la déclaration WHERE, donc je ne sais vraiment pas pourquoi select est si lent.

Quelqu'un pourrait-il me donner un indice pour résoudre ce problème?

est ici sql de table et requête

CREATE TABLE `messages` (
    `id` int(10) unsigned NOT NULL auto_increment, 
    `user_id` int(10) unsigned NOT NULL default '0', 
    `dest` varchar(20) character set latin1 default NULL, 
    `body` text character set latin1, 
    `sent_on` timestamp NOT NULL default CURRENT_TIMESTAMP, 
    `md5` varchar(32) character set latin1 NOT NULL default '', 
    `interface` enum('mobile','desktop') default NULL, 
    PRIMARY KEY (`id`), 
    KEY `user_id` (`user_id`), 
    KEY `md5` (`md5`), 
    FULLTEXT KEY `dest` (`dest`,`body`), 
    FULLTEXT KEY `body` (`body`) 
) ENGINE=MyISAM AUTO_INCREMENT=7074256 DEFAULT CHARSET=utf8 

et ici la requête:

EXPLAIN SELECT SQL_CALC_FOUND_ROWS id, sent_on, dest AS who, body,interface FROM messages WHERE user_id = 2 ORDER BY sent_on DESC LIMIT 0,50 \G; 
*************************** 1. row *************************** 
      id: 1 
    select_type: SIMPLE 
     table: messages 
     type: ref 
possible_keys: user_id 
      key: user_id 
     key_len: 4 
      ref: const 
     rows: 13997 
     Extra: Using where; Using filesort 
1 row in set (0.00 sec) 

Répondre

0

Notez les points suivants dans votre EXPLAIN sortie:

Extra: Using where; Using filesort 

Le Using filesort signifie que MySQL est le dumping de la requête résultats à un fichier pour le trier, puis en relisant les résultats pour obtenir les 50 premières lignes. Même si je ne suis pas un expert, je pense que vous pouvez optimiser ce processus en fournissant un index qui peut à la fois satisfaire les critères de sélection et trier l'ordre en une fois; alors la sélection et l'ordre peuvent être déterminés par un balayage d'index seulement, sans avoir à trier le jeu de résultats à chaque fois.

Dans ce cas, votre WHERE est sur user_id et votre ORDER BY sur sent_on. Donc, en théorie, si vous fournissez un seul index sur ces deux colonnes (dans cet ordre), alors le moteur pourra utiliser la première moitié de l'index pour filtrer les résultats, et parce que la seconde moitié de l'index est sur la colonne sent_on, les résultats de l'index seront déjà en ordre selon cette colonne, permettant à MySQL de simplement récupérer les 50 premiers résultats de cet index. Aucun tri supplémentaire requis.

Clause de non-responsabilité: Je ne suis pas un administrateur de base de données. Je peux me tromper complètement.

Voir aussi:Mysql.com: Multiple Column Indexes

+0

cela pourrait être une solution, ai-je juste ajouter un index sur (user_id, sent_on)? – n0cturnal

+0

Essayez-le et voyez si cela aide. ;-P – tylerl

+0

j'ai ajouté cet index, vous avez raison! Le fichier a disparu. Merci beaucoup! – n0cturnal

0

Peut-être que vous avez désactivé Concurrent Inserts?

+0

Juste à carreaux ...> SHOW VARIABLES LIKE '%% concomitante'; concurrent_insert | 1 – n0cturnal

0

Est-ce que ORDER BY pourrait vous ralentir? Je ne sais pas si une bonne idée de sent_on d'index, il dépend de SELECT vs INSERT fréquence

+0

Je vais essayer cette nuit, il est impossible d'exécuter une telle requête lourde sur une grande table de production. mais merci, je rapporterai ce qui se passera – n0cturnal

Questions connexes