Je vois un comportement de performance dans mysqld que je ne comprends pas.Une question de performance dans MySQL
J'ai une table t avec un identifiant de clé primaire et trois colonnes de données col1, ... col4.
Les données sont dans 4 fichiers TSV 'col1.tsv', ... 'col4.tsv'. La procédure que j'utilise pour les ingérer est:
CREATE TABLE t (
id INT NOT NULL,
col1 INT NOT NULL,
col2 INT NOT NULL,
col3 INT NOT NULL,
col4 CHAR(12) CHARACTER SET latin1 NOT NULL);
LOAD DATA LOCAL INFILE # POP 1
'col1.tsv' INTO TABLE t (id, col1);
ALTER TABLE t ADD PRIMARY KEY (id);
SET GLOBAL hot_keys.key_buffer_size= # something suitable
CACHE INDEX t IN hot_keys;
LOAD INDEX INTO CACHE t;
DROP TABLE IF EXISTS tmpt;
CREATE TABLE tmpt (id INT NOT NULL, val INT NOT NULL);
LOAD DATA LOCAL INFILE 'col2.tsv' INTO TABLE tmpt tt;
INSERT INTO t (id, col2) # POP 2
SELECT tt.id, tt.val FROM tmpt tt
ON DUPLICATE KEY UPDATE col2=tt.val;
DROP TABLE IF EXISTS tmpt;
CREATE TABLE tmpt (id INT NOT NULL, val INT NOT NULL);
LOAD DATA LOCAL INFILE 'col3.tsv' INTO TABLE tmpt tt;
INSERT INTO t (id, col3) # POP 3
SELECT tt.id, tt.val FROM tmpt tt
ON DUPLICATE KEY UPDATE col3=tt.val;
DROP TABLE IF EXISTS tmpt;
CREATE TABLE tmpt (id INT NOT NULL,
val CHAR(12) CHARACTER SET latin1 NOT NULL);
LOAD DATA LOCAL INFILE 'col4.tsv' INTO TABLE tmpt tt;
INSERT INTO t (id, col4) # POP 4
SELECT tt.id, tt.val FROM tmpt tt
ON DUPLICATE KEY UPDATE col4=tt.val;
Maintenant, voici la performance que je ne comprends pas. Parfois, les requêtes POP 2 et 3 INSERT INTO ... SELECT ... ON DUPLICATE KEY UPDATE tournent très vite avec mysqld occupant 100% d'un core et d'autres fois mysqld bogs à 1% de lecture CPU t.MYD, ie les données MyISAM de la table t fichier, à des décalages aléatoires.
J'ai eu beaucoup de mal à isoler dans quelles circonstances il est rapide et où il est lent, mais je l'ai trouvé un cas reproductible:
Dans la séquence ci-dessus, POP 2 et 3 sont très lents . Mais si je crée t sans col4 alors POP 2 et POP 3 sont très rapides. Pourquoi?
Et si, après cela, j'ajoute col4 avec une requête ALTER TABLE alors POP 4 exécute aussi très rapidement .
Encore une fois, lorsque les INSERT sont lents, mysqld est embourbé dans le fichier IO en lisant des décalages aléatoires dans le fichier de données MyISAM de la table t. Je ne comprends même pas pourquoi il lit ce fichier.
Version du serveur MySQL 5.0.87. OS X 10.6.4 sur Core 2 Duo iMac.
MISE À JOUR
J'ai finalement trouvé (ce que je pense) la réponse à cette question. La différence mystérieuse entre certains inserts étant lente et d'autres rapide dépend des données.
L'indice était: lorsque l'insertion est lente, mysqld cherche en moyenne 0,5 Go entre les lectures sur t.MYD. Quand il est rapide, les lectures successives ont de petits décalages relatifs. La confusion est survenue parce que certains des fichiers "col? .tsv" ont leurs rangs dans le même ordre de grandeur. la colonne id
tandis que d'autres sont ordonnées au hasard par rapport à eux.
J'ai été en mesure de réduire considérablement le temps de traitement global en utilisant sort (1) sur les fichiers tsv avant de les charger et de les insérer.
ce que vous essayez de faire - réponses droites seulement pls !! –
Il lit ce fichier parce que vous insérez dans ce fichier? – Danosaure
@ f00: J'essaye d'ingérer les fichiers TSV dans la table comme décrit dans les deuxième et troisième phrases de l'OP. –