Duplicate key causé par un SELECT

août 29, 2011

Parmi les erreurs courantes en MySQL, ont trouve la fameuse ERROR 1062 (23000): Duplicate entry ‘2984’ for key ‘PRIMARY’ causée par la tentative d’insertion d’une données, déjà présente, dans un colonne ayant une contrainte d’unicité.

Dans la même famille il y a aussi l’erreur 1022…

Une banale requête de lecture avec un GROUP BY:

mysql> SELECT DISTINCT(name), COUNT(name) FROM membre WHERE name <>  » GROUP BY name
ERROR 1022 (23000): Can’t write; duplicate key in table ‘/tmp/#sql_29lm_0’
 

C’est assez surprenant de trouver une telle erreur sur une requête aussi triviale !

En regardant le plan d’exécution, on remarque que outre le fait qu’ un index est plus que recommandé, MySQL créé une table temporaire (/tmp/#sql_29lm_0) et c’est en insérant les données dans cette dernière que le « duplicate key » se déclenche.

 
mysql> explain  SELECT DISTINCT(name), COUNT(name) FROM membre WHERE name <>  » GROUP BY name\G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: membre
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 92633696
Extra: Using where; Using temporary; Using filesort
 
Alors ça à tout l’air d’un bug, d’ailleurs 3 sont ouverts à ce sujet, pour les version 5.1 et 5.5 (le 1er depuis le 9 Nov 2010…):

http://bugs.mysql.com/bug.php?id=58081
http://bugs.mysql.com/bug.php?id=60808
http://bugs.mysql.com/bug.php?id=62097

Le contournement que j’ai trouvé à été d’augmenter pour la session, les caches utilisés par la requêtes, à savoir le max_heap_table_size et le tmp_table_size:

mysql> SET SESSION max_heap_table_size=536870912; SET SESSION tmp_table_size=536870912;
mysql> SELECT DISTINCT(name), COUNT(name) FROM membre WHERE name <>  » GROUP BY name
+—————+————-+
| name          | COUNT(name) |
+—————+————-+
|     Abano     |           3 |
 

Cela dit, ça serait quand même pas mal, qu’ Oracle fasse le nécessaire pour enfin corriger ce bug…

Leave a Reply