Jeśli chodzi o silnik pamięci MEMORY , oczekiwałbym, że kolejność będzie zgodna z kolejnością wstawiania, ponieważ HASH
zamiast tego domyślny układ indeksu BTREE
nie jest używany i żaden aspekt układu indeksu nie jest używany. Ponieważ zaindeksowałeś k, a k ma tę samą wartość, wszystkie klucze wchodzą do tego samego segmentu mieszania. Ponieważ nie ma powodu, aby zakładać dodatkową złożoność wypełniania segmentu mieszania, kolejność wstawiania jest najbardziej sensowna.
Wziąłem twoją próbną tabelę i dane i uruchomiłem 30 INSERT
s i otrzymałem to:
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>
Postanowiłem przetestować, dodając dwie różne wartości dla k: 10 i 11. Otrzymałem to:
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>
Wygląda na kolejność wstawiania. k = 11 to był pierwszy klucz zaszyfrowany, a następnie 10. Co powiesz na wstawienie 10 zamiast 11? Oto co mam:
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>
To jednogłośne !!! ZAMÓWIENIE WSTAWIENIA jest odpowiedzią.
Sidenotes na temat używania indeksów dla silnika pamięci MEMORY
Wyszukiwania MEMORY w zakresie zakresu miałyby porównywalnie przerażającą skuteczność.
Podczas tworzenia indeksu można określić USING BTREE
klauzulę wraz z definicją indeksu. Poprawiłoby to zakres zapytań o zakres.
Wyszukiwanie określonego wiersza da ten sam wynik w zakresie wydajności z jednym HASH
lub BTREE
.
AKTUALIZACJA 22.09.2011 11:18 EDT
Nauczyłem się dziś czegoś ciekawego. Przeczytałem link podany przez @Laurynas Biveinis z Percona: Link Percona mówi coś o tabelach MEMORY dla MySQL 5.5.15 :
Zamawianie rzędów
W przypadku braku ORDER BY rekordy mogą zostać zwrócone w innej kolejności niż poprzednia implementacja MEMORY. To nie jest błąd. Każda aplikacja oparta na konkretnym zamówieniu bez klauzuli ORDER BY może dawać nieoczekiwane wyniki. Określone zamówienie bez ORDER BY jest efektem ubocznym implementacji silnika pamięci i implementacji optymalizatora zapytań, który może i będzie się zmieniał między mniejszymi wersjami MySQL.
To był dla mnie dobry link do zobaczenia dzisiaj. Udzielona przeze mnie odpowiedź wykazała, że tabela, którą załadowałem, została pobrana w porządku, jakiego oczekiwałem DZIŚ w MySQL 5.5.12. Jak właśnie zauważyli Percona i @Laurynas Biveinis , nie ma gwarancji w innym mniejszym wydaniu.
Zamiast więc bronić mojej odpowiedzi, wolę promować odpowiedź od @Laurynas Biveinis, ponieważ jest to najbardziej aktualna informacja. Wyrazy uznania i czapki dla @Laurynas Biveinis . Chciałbym również podziękować @eevar za grzeczne zwrócenie uwagi na nie promowanie odpowiedzi na pytania dotyczące konkretnych wersji. Obaj otrzymali dziś moje poparcie.