En ce qui concerne le moteur de stockage MEMORY , je m'attendrais à ce que l'ordre soit classé par ordre d'insertion, car la disposition d'index par défaut est HASH
remplacée par BTREE
aucun élément de la disposition d'index n'est utilisé. Puisque vous avez indexé k et que k a la même valeur, toutes les clés entrent dans le même panier de hachage. Comme il n’ya aucune raison d’assumer une complexité supplémentaire lors du remplissage d’un panier de hachage, l’ordre d’insertion a plus de sens.
J'ai pris votre même exemple de table et de données INSERT
et ai couru pendant 30 secondes.
mysql> use test
Database changed
mysql> drop table if exists t;
Query OK, 0 rows affected (0.00 sec)
mysql> create table t(k int, v int,index k(k)) engine=memory;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t values
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3);
Query OK, 30 rows affected (0.00 sec)
Records: 30 Duplicates: 0 Warnings: 0
mysql> select * from t;
+------+------+
| k | v |
+------+------+
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
+------+------+
30 rows in set (0.00 sec)
mysql>
J'ai décidé de tester en ajoutant deux valeurs différentes pour k: 10 et 11.
mysql> use test
Database changed
mysql> drop table if exists t;
Query OK, 0 rows affected (0.02 sec)
mysql> create table t(k int, v int,index k(k)) engine=memory;
Query OK, 0 rows affected (0.01 sec)
mysql> insert into t values
-> (11, 1), (11, 2), (11, 3), (10, 1), (10, 2), (10, 3),
-> (11, 1), (11, 2), (11, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3);
Query OK, 30 rows affected (0.00 sec)
Records: 30 Duplicates: 0 Warnings: 0
mysql> select * from t;
+------+------+
| k | v |
+------+------+
| 11 | 1 |
| 11 | 2 |
| 11 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 11 | 1 |
| 11 | 2 |
| 11 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
+------+------+
30 rows in set (0.00 sec)
mysql>
Ressemble à l'ordre d'insertion. k = 11 était la première clé hachée puis 10. Qu'en est-il d'insérer 10 en premier au lieu de 11? C'est ce que j'ai eu:
mysql> use test
Database changed
mysql> drop table if exists t;
Query OK, 0 rows affected (0.02 sec)
mysql> create table t(k int, v int,index k(k)) engine=memory;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into t values
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (11, 1), (11, 2), (11, 3), (10, 1), (10, 2), (10, 3),
-> (11, 1), (11, 2), (11, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3),
-> (10, 1), (10, 2), (10, 3), (10, 1), (10, 2), (10, 3);
Query OK, 30 rows affected (0.00 sec)
Records: 30 Duplicates: 0 Warnings: 0
mysql> select * from t;
+------+------+
| k | v |
+------+------+
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 11 | 1 |
| 11 | 2 |
| 11 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 11 | 1 |
| 11 | 2 |
| 11 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
| 10 | 1 |
| 10 | 2 |
| 10 | 3 |
+------+------+
30 rows in set (0.00 sec)
mysql>
C'est unanime !!! ORDER OF INSERTION est la réponse.
Notes de bas de page sur l'utilisation des index pour le moteur de stockage MEMORY
Les recherches de plage pour MEMORY auraient des performances comparables.
Lors de la création d'un index, vous pouvez spécifier une USING BTREE
clause avec la définition de l'index. Cela améliorerait les choses pour les requêtes de plage.
La recherche d'une ligne spécifique produira le même résultat en termes de performances avec HASH
ou BTREE
.
MISE À JOUR 2011-09-22 11:18 EDT
J'ai appris quelque chose d'intéressant aujourd'hui. J'ai lu le lien fourni par @Laurynas Biveinis de Percona: Le lien Percona en dit long sur les tables MEMORY pour MySQL 5.5.15 :
Commande de rangées
En l'absence de ORDER BY, les enregistrements peuvent être renvoyés dans un ordre différent de celui de l'implémentation précédente de MEMORY. Ce n'est pas un bug. Toute application reposant sur un ordre spécifique sans clause ORDER BY peut générer des résultats inattendus. Un ordre spécifique sans ORDER BY est l’effet secondaire de l’implémentation d’un moteur de stockage et de l’optimiseur de requêtes qui peut et va changer entre les versions mineures de MySQL.
C'était un bon lien pour moi à voir aujourd'hui. La réponse que j'ai donnée montre que la table que j'ai chargée a été récupérée dans l'ordre que je prévoyais aujourd'hui dans MySQL 5.5.12. Comme l'ont souligné Percona et @Laurynas Biveinis , il n'y a aucune garantie dans une autre version mineure.
Donc, plutôt que d'essayer de défendre ma réponse, je préférerais promouvoir la réponse de @Laurynas Biveinis parce que c'est l'information la plus récente. Bravo et chapeau pour @Laurynas Biveinis . Je tiens également à remercier @eevar d’ avoir fait remarquer poliment de ne pas promouvoir les réponses aux questions par version. Ils ont tous deux mon vote positif aujourd'hui.