Respostas:
Reposicionando minha resposta para uma pergunta semelhante sobre o SQL Server:
No mundo SQL, a ordem não é uma propriedade inerente a um conjunto de dados. Assim, você não recebe garantias do seu RDBMS de que seus dados retornarão em uma determinada ordem - ou mesmo em uma ordem consistente - a menos que você os consulte com uma cláusula ORDER BY.
Então, para responder sua pergunta:
ORDER BY
. Fazer qualquer outra coisa é se preparar para surpresas indesejadas.Esta é uma propriedade de todo o SQL, não apenas do MySQL. O texto relevante na especificação SQL-92 é:
Se uma <ordem por cláusula> não for especificada, a ordem das linhas de Q depende da implementação.
Existem bits de texto semelhantes nas especificações dos cursores.
A ordem das linhas na ausência de ORDER BY
cláusula pode ser:
A inserção é desordenada, caótica, à chegada. O índice que é criado tem ordem em que os elementos são inseridos no local apropriado na lista vinculada que é o índice. Pense em uma lista triplamente vinculada a um índice, onde você tem um link de avanço de um elemento de índice para o próximo, um link de retrospectiva para propósitos de travessia e integridade e, em seguida, um conjunto de indicadores para os registros reais da tabela que corresponde ao elemento indexado em questão.
Dados reais, caóticos no armazenamento. Índice associado aos dados, ordenados em armazenamento e construção. A atração real de dados, ordenada ou não, depende da consulta envolvida.
Quando se trata do mecanismo de armazenamento MEMORY , eu esperaria que a ordem fosse pela ordem de inserção, porque o layout de índice padrão está em HASH
vez de BTREE
e nenhum aspecto do layout de índice está sendo usado. Como você indexou k, ek é o mesmo valor, todas as chaves entram no mesmo intervalo de hash. Como não há motivo para assumir complexidade adicional ao preencher um hash bucket, a ordem de inserção faz mais sentido.
Peguei sua mesma tabela de amostra e dados e executei 30 se INSERT
obtive o seguinte:
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>
Decidi testar adicionando dois valores diferentes para k: 10 e 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>
Parece ordem de inserção. k = 11 foi o primeiro hash da chave, em seguida, 10. Que tal inserir 10 primeiro em vez de 11? Isto é o que eu tenho:
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>
É unânime !!! ORDEM DE INSERÇÃO é a resposta.
Notas de rosto sobre o uso de índices para o mecanismo de armazenamento MEMORY
As pesquisas por intervalo de MEMORY teriam um desempenho comparativamente horrível.
Ao criar um índice, você pode especificar a USING BTREE
cláusula junto com a definição do índice. Isso melhoraria as coisas para consultas de intervalo.
Procurar uma linha específica produzirá o mesmo resultado no desempenho com HASH
ou BTREE
.
ATUALIZAÇÃO 22-09-2011 11:18 EDT
Eu aprendi algo interessante hoje. Eu li o link fornecido por @Laurynas Biveinis da Percona: O link Percona diz algo sobre as tabelas MEMORY para MySQL 5.5.15 :
Ordenação de linhas
Na ausência de ORDER BY, os registros podem ser retornados em uma ordem diferente da implementação anterior de MEMORY. Isso não é um bug. Qualquer aplicativo que confie em um pedido específico sem uma cláusula ORDER BY pode fornecer resultados inesperados. Uma ordem específica sem ORDER BY é um efeito colateral da implementação de um mecanismo de armazenamento e otimizador de consultas que pode e irá mudar entre versões menores do MySQL.
Este foi um bom link para eu ver hoje. A resposta que eu dei demonstrou que a tabela que eu carregava foi recuperada na ordem que eu esperava HOJE no MySQL 5.5.12. Como apontado por Percona e @Laurynas Biveinis , não há garantia em outro lançamento menor.
Portanto, em vez de tentar defender minha resposta, prefiro promover a resposta de @Laurynas Biveinis porque é a informação mais atual. Parabéns e elogios para @Laurynas Biveinis . Também gostaria de agradecer à @eevar por educadamente apontar para não promover respostas específicas a versões para perguntas. Ambos recebem meu voto hoje.