V InnoDB , jsou řádky uloženy v pořadí primárního klíče. Pokud používáte LIMIT
bez ORDER BY
, vždy získáte řádky s nejnižšími hodnotami primárního klíče, i když je vložíte v náhodném pořadí.
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 |
+----+------+------+
V MyISAM , řádky se ukládají, kam se vejdou. Zpočátku to znamená, že řádky jsou připojeny k datovému souboru, ale jak odstraníte řádky a vložíte nové, mezery po smazaných řádcích budou znovu použity novými řádky.
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
+----+------+------+
Dalším výjimečným případem, pokud používáte InnoDB, je situace, kdy načítáte řádky ze sekundárního indexu namísto z primárního indexu. To se stane, když ve výstupu EXPLAIN uvidíte poznámku "Using index".
alter table foo add index (x);
select id, x from foo;
+----+------+
| id | x |
+----+------+
| 5 | A |
| 9 | B |
| 2 | C |
| 4 | D |
| 1 | E |
+----+------+
Pokud máte složitější dotazy se spojeními, bude to ještě komplikovanější, protože získáte řádky vrácené podle výchozího pořadí první tabulky, ke které se přistupuje (kde „první“ závisí na optimalizátoru, který zvolí pořadí tabulek), pak řádky ze spojené tabulky budou závislé na pořadí řádků z předchozí tabulky.
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 |
+----+------+------+----+------+------+
Pointa je, že je nejlepší být explicitní:když používáte LIMIT
, zadejte ORDER BY
.