InnoDB insère très lent et le ralentissement de

J'ai récemment changé mon projet de tables InnoDB (penser les relations seraient une bonne chose à avoir). J'utilise un script PHP pour l'index de près de 500 produits à la fois.

Une table de stockage de mot/id de l'association:

    CREATE TABLE `windex` (
 `word` varchar(64) NOT NULL,
 `wid` int(10) unsigned NOT NULL AUTO_INCREMENT,
 `count` int(11) unsigned NOT NULL DEFAULT '1',
 PRIMARY KEY (`wid`),
 UNIQUE KEY `word` (`word`)
) ENGINE=InnoDB AUTO_INCREMENT=324551 DEFAULT CHARSET=latin1

Une autre table stocke l'id du produit/mot id associations:

CREATE TABLE `indx_0` (
 `wid` int(7) unsigned NOT NULL,
 `pid` int(7) unsigned NOT NULL,
 UNIQUE KEY `wid` (`wid`,`pid`),
 KEY `pid` (`pid`),
 CONSTRAINT `indx_0_ibfk_1` FOREIGN KEY (`wid`) REFERENCES `windex` (`wid`) ON DELETE CASCADE ON UPDATE CASCADE,
 CONSTRAINT `indx_0_ibfk_2` FOREIGN KEY (`pid`) REFERENCES `product` (`ID`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Le script a été testé à l'aide de MyISAM et index des produits relativement rapide (beaucoup, beaucoup plus rapide que InnoDB). La première fois que l'exécution en InnoDB il était ridiculement lent mais après l'imbrication des valeurs plus ensemble, j'ai fini par l'accélérer par beaucoup (mais pas assez).

Je suppose que innodb serait beaucoup plus rapide pour ce genre de chose, car de rowlevel serrures mais ce n'est pas le cas.

Je construire une requête qui ressemble à quelque chose comme:

SELECT
title,keywords,upc,...
FROM product
WHERE indexed = 0
LIMIT 500

J'ai créer une boucle et remplir un tableau avec tous les mots qui doivent être ajoutés à windex et tous le mot id/id de produit paires qui doivent être ajoutés à indx_0.

Parce que innodb ne cesse de monter mon auto-incrémentation des valeurs à chaque fois que je fais un "REMPLACER par" ou "INSÉRER IGNORER" qui échoue à cause de doublons, j'ai besoin de s'assurer que les valeurs-je ajouter n'existent pas déjà. Pour le faire j'ai d'abord sélectionner toutes les valeurs qui existent à l'aide d'une requête comme tel:

SELECT wid,word
FROM windex
WHERE
word = "someword1" or word = "someword2" or word = "someword3" ... ...

Puis je filtre mon tableau par rapport aux résultats qui existent, pour tous les nouveaux mots que j'ai ajouter sont 100% nouveau.

Cela prend environ 20% du temps d'exécution global. Les autres 80% va dans ajout de la paire de valeurs dans indx_0, pour lequel il y a beaucoup plus de valeurs.

Voici un exemple de ce que je reçois.

0.4806 secondes pour sélectionner les produits. (0.4807 sec total).

0.0319 secondes pour rassembler les 500 articles. (0.5126 sec total).

5.2396 secondes pour sélectionner windex valeurs à des fins de comparaison. (5.7836 sec total).

1.8986 secondes pour le nombre de mises à jour. (7.6822 sec total).

0.0641 secondes pour ajouter 832 windex enregistrements. (7.7464 sec total).

17.2725 secondes pour ajouter de l'indice de 3435 pid/wid paires. (25.7752 sec total).

L'opération a pris 26.07 secondes à l'indice 500 de produits.

La 3435 paires sont toutes exécutées en une seule requête telle que:

INSERT INTO indx_0(pid,wid)
VALUES (1,4),(3,9),(9,2)... ... ...

Pourquoi est-InnoDB beaucoup plus lent que MyISAM dans mon cas?

C'est l'idée de la parole de l'indice de créer un certain type de fonctionnalité de recherche? Si c'est le cas, il été fait, découvrez un véritable moteur de recherche comme solr ou de recherche fulltext mysql par exemple. Ne peut pas surpasser ces tâches spécifiques.

OriginalL'auteur nick | 2012-02-02