kno*_*orv 17 mysql select sql-order-by
假设向MySQL数据库发出以下查询:
SELECT * FROM table_name;
Run Code Online (Sandbox Code Playgroud)
请注意,没有 ORDER BY给出任何条款.
我的问题是:
MySQL是否给出了结果集行的顺序保证?
更具体地说,我可以假设行将按插入顺序返回吗?这与行插入表中的顺序相同.
Bil*_*win 29
不,没有保证.除非您使用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 |
+----+---------+
Run Code Online (Sandbox Code Playgroud)
所以现在我们有六行.此时的存储包含第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 |
+----+---------+
Run Code Online (Sandbox Code Playgroud)
请注意在将新行附加到表的末尾之前,MySQL如何重复使用通过删除行打开的空格.还要注意,行11到14以相反的顺序插入这些空间,从末端向后填充.
因此,存储行的顺序与它们的插入顺序不完全相同.
你不能。
有时 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;
Run Code Online (Sandbox Code Playgroud)
MySQL几乎总是使用该key_lookup键对此表进行任何选择操作;由于permKey是第一个字段,因此通常会按此键“排序”(按字母顺序显示,但不完全如此)。
如果没有ORDER BY子句,MySQL(以及大多数/所有 RDBMS 引擎)将尝试以尽可能快的速度获取存储的数据。