假设向MySQL数据库发出以下查询:
SELECT * FROM table_name;
请注意,没有 ORDER BY
条款。
我的问题是:
MySQL是否对结果集行的顺序给出任何保证?
更具体地说,我可以假设行将按插入顺序返回吗?这与行插入表中的顺序相同。
答案 0 :(得分:27)
不,没有保证。除非您使用ORDER BY
子句指定订单,否则订单完全取决于内部实施细节。即对RDBMS引擎来说最方便的一切。
实际上,行可能以原始插入顺序返回(或者更准确地说是行存在于物理存储中的顺序),但您不应该依赖于此。如果您将应用程序移植到另一个品牌的RDBMS,或者即使您升级到可能以不同方式实现存储的更新版本的MySQL,行也可能会以其他顺序返回。
对于任何符合SQL的RDBMS,后一点都适用。
以下是存储中行存在顺序与存储顺序的比较:
CREATE TABLE foo (id SERIAL PRIMARY KEY, bar CHAR(10));
-- create rows with id 1 through 10
INSERT INTO foo (bar) VALUES
('testing'), ('testing'), ('testing'), ('testing'), ('testing'),
('testing'), ('testing'), ('testing'), ('testing'), ('testing');
DELETE FROM foo WHERE id BETWEEN 4 AND 7;
+----+---------+
| id | bar |
+----+---------+
| 1 | testing |
| 2 | testing |
| 3 | testing |
| 8 | testing |
| 9 | testing |
| 10 | testing |
+----+---------+
所以现在我们有六行。此时的存储包含第3行和第8行之间的间隙,在删除中间行后留下。删除行不会对这些间隙进行碎片整理。
-- create rows with id 11 through 20
INSERT INTO foo (bar) VALUES
('testing'), ('testing'), ('testing'), ('testing'), ('testing'),
('testing'), ('testing'), ('testing'), ('testing'), ('testing');
SELECT * FROM foo;
+----+---------+
| id | bar |
+----+---------+
| 1 | testing |
| 2 | testing |
| 3 | testing |
| 14 | testing |
| 13 | testing |
| 12 | testing |
| 11 | testing |
| 8 | testing |
| 9 | testing |
| 10 | testing |
| 15 | testing |
| 16 | testing |
| 17 | testing |
| 18 | testing |
| 19 | testing |
| 20 | testing |
+----+---------+
注意在将新行附加到表的末尾之前,MySQL如何重复使用通过删除行打开的空格。还要注意,行11到14以相反的顺序插入这些空间,从末端向后填充。
因此,存储行的顺序与插入行的顺序不完全相同。
答案 1 :(得分:5)
Per this thread,默认排序是MyISAM的插入顺序,InnoDB的主键升序。但我不认为这是一种保证,只是它的工作原理。
答案 2 :(得分:4)
不,你不能。
有时,MySQL会使用您不期望的键执行选择查询。考虑一下这个表:
CREATE TABLE `user_permissions` (
`permId` int(5) unsigned NOT NULL AUTO_INCREMENT,
`permKey` varchar(16) NOT NULL,
`permDesc` varchar(64) DEFAULT NULL,
PRIMARY KEY (`permId`),
KEY `key_lookup` (`permKey`,`permId`,`permDesc`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
MySQL几乎总是使用key_lookup
键对该表执行任何选择操作;由于permKey
是第一个字段,因此它通常会被此键“排序”(按字母顺序排列,但不完全相同)。
如果没有ORDER BY
子句,MySQL(以及大多数/所有RDBMS引擎)将尽可能快地获取数据。
答案 3 :(得分:2)
来自Retrieving Data Using the MySQL SELECT Statement : The SELECT Statement
显示的数据未订购。 通常在中检索记录 它们的插入顺序相同 进入数据库
是的,根据评论
虽然记录正常 按照他们的顺序检索 你插入到数据库中 不能依赖特定的订单 被保存。如果您的数据库是 备份和恢复,或者如果是 执行维护操作 数据库,MySQL可能会改变 存储记录的顺序 内部。
答案 4 :(得分:1)
不,绝对不是。根据您正在使用的数据库引擎(ISAM或InnoDB),表结构将generally be some kind of b-tree以允许更快地搜索行。这与插入顺序无关,更多的是与数据库如何基于主键构建索引(或者在没有键的情况下,如何存储表堆)。
答案 5 :(得分:0)
默认情况下,在插入顺序中没有选择mysql 5.6中的结果,你可以进行更新等,并按任何顺序重新启动查询