1

J'ai écrit une procédure stockée dans MySQL pour prendre les valeurs actuellement dans une table et les "normaliser". Cela signifie que pour chaque valeur transmise à la procédure stockée, elle vérifie si la valeur est déjà dans la table. Si c'est le cas, alors il stocke l'identifiant de cette ligne dans une variable. Si la valeur n'est pas dans la table, elle stocke l'identifiant de la nouvelle valeur insérée. La procédure stockée prend ensuite les identifiants et les insère dans une table qui est équivalente à la table normalisée originale, mais cette table est entièrement normalisée et se compose principalement de clés étrangères. Mon problème avec cette conception est que la procédure stockée prend environ 10ms ou plus pour revenir, ce qui est trop long lorsque vous essayez de travailler sur 10 millions d'enregistrements. Mon soupçon est que la performance est à voir avec la façon dont je fais les inserts. à savoirMySQL Normalisation procédure stockée performance

INSERT INTO TableA 
(first_value) 
VALUES 
(argument_from_sp) ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id); 

SET @TableAId = LAST_INSERT_ID(); 

Le « Duplicate KEY UPDATE » est un peu un hack, en raison du fait que sur une clé en double, je ne veux pas mettre à jour quoi que ce soit, mais plutôt juste retour l'identifiant de la ligne. Si vous manquez cette étape, la fonction LAST_INSERT_ID() renvoie la valeur incorrecte lorsque vous essayez d'exécuter l'instruction "SET ...".

Est-ce que quelqu'un connaît une meilleure façon de faire cela dans MySQL?

Répondre

2

Je suis retourné et créé une fonction pour gérer ce cas à la place:

CREATE DEFINER=`root`@`%` FUNCTION `value_update`(inValue VARCHAR(255)) RETURNS int(11) 
BEGIN 
     DECLARE outId INT; 
     SELECT valueId INTO outId FROM ValuesTable WHERE value = inValue; 

     IF outId IS NULL THEN 
       INSERT INTO ValuesTable (value) VALUES (inValue); 
       SELECT LAST_INSERT_ID() INTO outId; 
     END IF; 

     RETURN outId; 
END 

La procédure stockée mentionné plus tôt appelle ces fonctions au lieu de faire les déclarations INSERT lui-même. Côté performance, la fonction ci-dessus est plus rapide dans ma configuration (en utilisant le type de table ndb). De plus, après avoir analysé toutes les parties de mon application, j'ai constaté que les problèmes de performance que cela causait n'étaient qu'une partie mineure du goulot d'étranglement global des performances.

0

Si vous avez déjà un identifiant unique, est-il nécessaire d'avoir une clé primaire auto-incrémentée?

+0

L'identificateur unique serait autrement un champ VARCHAR. Je préférerais un champ entier pour des raisons de performances. – srkiNZ84

+0

L'identifiant unique est toujours un champ varchar; tout ce que vous avez fait est d'ajouter une autre colonne et un autre index unique à la table. L'identificateur unique entier ne sert à rien et le mieux que l'on puisse en dire est qu'il ne ralentira pas beaucoup les choses. L'analyse comparative de toutes les parties de votre demande a été une bonne idée et vous permettra de vous concentrer sur les choses importantes. –