sql >> Base de Datos >  >> RDS >> Mysql

Cómo se ordenan los datos en MySql por defecto

En InnoDB , las filas se almacenan en orden de clave principal. Si usa LIMIT sin ORDER BY , siempre obtendrá las filas con los valores de clave principal más bajos, incluso si los insertó en orden aleatorio.

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 |
+----+------+------+

En MiISAM , las filas se almacenan donde caben. Inicialmente, esto significa que las filas se agregan al archivo de datos, pero a medida que elimina filas e inserta otras nuevas, los espacios que dejan las filas eliminadas serán reutilizados por filas nuevas.

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
+----+------+------+

Otro caso de excepción si usa InnoDB es si está recuperando filas de un índice secundario en lugar del índice primario. Esto sucede cuando ve la nota "Usando el índice" en la salida de 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 tiene consultas más complejas con uniones, se vuelve aún más complicado, porque obtendrá las filas devueltas en el orden predeterminado de la primera tabla a la que se accede (donde "primero" depende de que el optimizador elija el orden de las tablas), luego las filas de la tabla unida dependerán del orden de las filas de la tabla anterior.

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 |
+----+------+------+----+------+------+

La conclusión es que es mejor ser explícito:cuando usa LIMIT , especifica un ORDER BY .