Trong InnoDB , các hàng được lưu trữ theo thứ tự khóa chính. Nếu bạn sử dụng LIMIT
không có ORDER BY
, bạn sẽ luôn nhận được các hàng có giá trị khóa chính thấp nhất, ngay cả khi bạn đã chèn chúng theo thứ tự ngẫu nhiên.
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 |
+----+------+------+
Trong MyISAM , các hàng được lưu trữ ở bất kỳ nơi nào chúng vừa vặn. Ban đầu, điều này có nghĩa là các hàng được nối vào tệp dữ liệu, nhưng khi bạn xóa các hàng và chèn các hàng mới, khoảng trống do các hàng đã xóa để lại sẽ được các hàng mới sử dụng lại.
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
+----+------+------+
Một trường hợp ngoại lệ khác nếu bạn sử dụng InnoDB là nếu bạn đang truy xuất các hàng từ chỉ mục phụ thay vì từ chỉ mục chính. Điều này xảy ra khi bạn thấy ghi chú "Sử dụng chỉ mục" trong đầu ra GIẢI THÍCH.
alter table foo add index (x);
select id, x from foo;
+----+------+
| id | x |
+----+------+
| 5 | A |
| 9 | B |
| 2 | C |
| 4 | D |
| 1 | E |
+----+------+
Nếu bạn có các truy vấn phức tạp hơn với các phép nối, nó thậm chí còn phức tạp hơn, vì bạn sẽ nhận được các hàng được trả về theo thứ tự mặc định của bảng đầu tiên được truy cập (trong đó "đầu tiên" phụ thuộc vào trình tối ưu hóa chọn thứ tự các bảng), sau đó các hàng từ bảng đã kết hợp sẽ phụ thuộc vào thứ tự của các hàng từ bảng trước đó.
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 |
+----+------+------+----+------+------+
Điểm mấu chốt là tốt nhất nên rõ ràng: khi bạn sử dụng LIMIT
, chỉ định một ORDER BY
.