Wenn es um die Speicher-Engine MEMORY geht , würde ich erwarten, dass die Reihenfolge nach Einfügereihenfolge erfolgt, da HASH
stattdessen das Standard-Index-Layout verwendet wird BTREE
und keiner der Aspekte des Index-Layouts verwendet wird. Da Sie k indiziert haben und k der gleiche Wert ist, geben alle Schlüssel den gleichen Hash-Bucket ein. Da es keinen Grund gibt, zusätzliche Komplexität beim Auffüllen eines Hash-Buckets anzunehmen, ist die Reihenfolge des Einfügens am sinnvollsten.
Ich habe dieselbe Probentabelle und dieselben Daten genommen und 30 INSERT
Sekunden lang ausgeführt.
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>
Ich habe mich dazu entschlossen, zwei verschiedene Werte für k: 10 und 11 zu addieren.
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>
Sieht aus wie Reihenfolge der Einfügung. k = 11 war der erste Schlüssel gehasht dann 10. Was ist mit dem Einfügen von 10 zuerst anstelle von 11? Das habe ich bekommen:
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>
Es ist einstimmig !!! INSERTIONSORDNUNG ist die Antwort.
Anmerkungen zur Verwendung von Indizes für die MEMORY-Speicher-Engine
Die Reichweitensuche nach MEMORY hätte eine vergleichsweise horrende Leistung.
Beim Erstellen eines Index können Sie eine USING BTREE
Klausel zusammen mit der Definition des Index angeben . Dies würde Dinge für Bereichsabfragen verbessern.
Wenn Sie nach einer bestimmten Zeile suchen, erhalten Sie mit HASH
oder dasselbe Ergebnis bei der Leistung BTREE
.
UPDATE 2011-09-22 11:18 EDT
Ich habe heute etwas Interessantes gelernt. Ich habe den Link von @Laurynas Biveinis aus Percona gelesen: Der Percona-Link sagt etwas über MEMORY-Tabellen für MySQL 5.5.15 aus :
Reihenbestellung
Ohne ORDER BY können Datensätze in einer anderen Reihenfolge als in der vorherigen MEMORY-Implementierung zurückgegeben werden. Dies ist kein Fehler. Jede Anwendung, die auf eine bestimmte Bestellung ohne ORDER BY-Klausel angewiesen ist, kann unerwartete Ergebnisse liefern. Eine bestimmte Reihenfolge ohne ORDER BY ist ein Nebeneffekt einer Implementierung einer Speicher-Engine und eines Abfrageoptimierers, der sich zwischen kleineren MySQL-Versionen ändern kann und wird.
Dies war ein guter Link für mich, um ihn heute zu sehen. Die Antwort, die ich gegeben habe, hat gezeigt, dass die von mir geladene Tabelle abgerufen wurde, damit ich HEUTE in MySQL 5.5.12 rechne. Wie von Percona und @Laurynas Biveinis bereits erwähnt , gibt es in einer anderen kleineren Version keine Garantie.
Anstatt zu versuchen, meine Antwort zu verteidigen, möchte ich lieber die Antwort von @Laurynas Biveinis bewerben, da dies die aktuellste Information ist. Ein großes Lob und einen Hut ab für @Laurynas Biveinis . Ich möchte @eevar auch dafür danken, dass er höflich darauf hingewiesen hat, keine versionsspezifischen Antworten auf Fragen zu veröffentlichen. Sie beide bekommen heute meine Zustimmung.