Mysql
 sql >> Base de données >  >> RDS >> Mysql

Comment les données sont triées dans MySql par défaut

Dans InnoDB , les lignes sont stockées dans l'ordre des clés primaires. Si vous utilisez LIMIT sans ORDER BY , vous obtiendrez toujours les lignes avec les valeurs de clé primaire les plus basses, même si vous les avez insérées dans un ordre aléatoire.

create table foo (id int primary key, x char(1), y int) engine=InnoDB;
insert into foo values (5, 'A', 123);
insert into foo values (9, 'B', 234);
insert into foo values (2, 'C', 345);
insert into foo values (4, 'D', 456);
insert into foo values (1, 'E', 567);
select * from foo;
+----+------+------+
| id | x    | y    |
+----+------+------+
|  1 | E    |  567 |
|  2 | C    |  345 |
|  4 | D    |  456 |
|  5 | A    |  123 |
|  9 | B    |  234 |
+----+------+------+

Dans MyISAM , les lignes sont stockées à leur place. Initialement, cela signifie que les lignes sont ajoutées au fichier de données, mais lorsque vous supprimez des lignes et en insérez de nouvelles, les espaces laissés par les lignes supprimées seront réutilisés par de nouvelles lignes.

create table bar (id int primary key, x char(1), y int) engine=MyISAM;
insert into bar values (1, 'A', 123);
insert into bar values (2, 'B', 234);
insert into bar values (3, 'C', 345);
insert into bar values (4, 'D', 456);
insert into bar values (5, 'E', 567);
select * from bar;
+----+------+------+
| id | x    | y    |
+----+------+------+
|  1 | A    |  123 |
|  2 | B    |  234 |
|  3 | C    |  345 |
|  4 | D    |  456 |
|  5 | E    |  567 |
+----+------+------+
delete from bar where id between 3 and 4;
insert into bar values (6, 'F', 678);
insert into bar values (7, 'G', 789);
insert into bar values (8, 'H', 890);
select * from bar;
+----+------+------+
| id | x    | y    |
+----+------+------+
|  1 | A    |  123 |
|  2 | B    |  234 |
|  7 | G    |  789 | <-- new row fills gap
|  6 | F    |  678 | <-- new row fills gap
|  5 | E    |  567 |
|  8 | H    |  890 | <-- new row appends at end
+----+------+------+

Un autre cas d'exception si vous utilisez InnoDB est si vous récupérez des lignes à partir d'un index secondaire au lieu de l'index primaire. Cela se produit lorsque vous voyez la note "Utilisation de l'index" dans la sortie EXPLAIN.

alter table foo add index (x);
select id, x from foo;
+----+------+
| id | x    |
+----+------+
|  5 | A    |
|  9 | B    |
|  2 | C    |
|  4 | D    |
|  1 | E    |
+----+------+

Si vous avez des requêtes plus complexes avec des jointures, cela devient encore plus compliqué, car vous obtiendrez les lignes renvoyées par l'ordre par défaut de la première table accédée (où "premier" dépend de l'optimiseur choisissant l'ordre des tables), puis les lignes de la table jointe dépendront de l'ordre des lignes de la table précédente.

select straight_join foo.*, bar.* from bar join foo on bar.x=foo.x;
+----+------+------+----+------+------+
| id | x    | y    | id | x    | y    |
+----+------+------+----+------+------+
|  1 | E    |  567 |  5 | E    |  567 |
|  5 | A    |  123 |  1 | A    |  123 |
|  9 | B    |  234 |  2 | B    |  234 |
+----+------+------+----+------+------+

select straight_join foo.*, bar.* from foo join bar on bar.x=foo.x;
+----+------+------+----+------+------+
| id | x    | y    | id | x    | y    |
+----+------+------+----+------+------+
|  5 | A    |  123 |  1 | A    |  123 |
|  9 | B    |  234 |  2 | B    |  234 |
|  1 | E    |  567 |  5 | E    |  567 |
+----+------+------+----+------+------+

En fin de compte, il est préférable d'être explicite :lorsque vous utilisez LIMIT , spécifiez un ORDER BY .