对于省略orderby子句的mysql innodb查询,“defaultorderby”是什么?

bxjv4tth  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(384)

因此,我了解并发现一些帖子指出,当您从dbms检索数据时,不建议在sql查询中省略ORDERBY子句。
资源和咨询后(将更新):
sql server联合-默认的行为顺序是什么
当没有指定“order by”时,查询会为记录集选择什么顺序?
https://dba.stackexchange.com/questions/6051/what-is-the-default-order-of-records-for-a-select-statement-in-mysql
问题:
如果您想了解更多,请参阅下面问题的逻辑。
我的问题是:在使用innodb引擎的mysql下,有人知道dbms如何有效地给出结果吗?
我读到它依赖于实现,好吧,但是对于我当前的实现,有没有办法知道它呢?
这到底是在哪里定义的?
它是来自mysql、innodb还是依赖于操作系统?
外面不是有什么单子吗?
最重要的是,如果省略order by子句并得到结果,我不能确定这段代码是否仍然适用于较新的数据库版本,dbms是否永远不会给出相同的结果,对吗?
用例逻辑(&L):
我目前正在编写一个crudapi,我的db中有一个不包含“id”字段的表(虽然有一个pk),所以当我在没有任何研究标准的情况下显示该表的结果时,我真的不知道应该使用什么来排序结果。我的意思是,我可以使用pk或任何永远不为null的字段,但这不会使它相关。所以我想知道,因为我的crud应该适用于任何表,我不想通过为这个特定表添加一个异常来解决这个问题,所以我也可以省略orderby子句。
最后说明:
当我阅读其他文章、示例和代码示例时,我觉得我想做得太过分了。我理解,众所周知,在请求中省略order by子句是一种不好的做法,并且没有可靠的默认order子句,也不是说除非您指定它,否则根本就没有order。
我只想知道它是在哪里定义的,并且想了解它是如何在内部工作的,或者至少是在哪里定义的(dbms/存储引擎/os依赖性/其他/多个标准)。我认为了解它,了解这里的内在机制,对其他人也有好处。
谢谢你抽出时间来阅读!祝您有个美好的一天。

vwoqyblh

vwoqyblh1#

比尔的回答很好。但不完整。
如果查询是 UNION ,我认为它将首先交付 SELECT (根据规则),然后是第二个结果。另外,如果table是 PARTITIONed ,它很可能会做类似的事情。 GROUP BY 可以按分组表达式排序,从而得到可预测的顺序,也可以使用散列技术对行进行置乱。我不知道该怎么预测。
派生表过去是一个有序列表,它传播到父查询的排序中。但最近 ORDER BY 正在子查询中被丢弃(除非有 LIMIT .)
底线:如果您关心订单,请添加 ORDER BY ,即使从这个问答看来没有必要。
相比之下,myisam从这个前提开始:默认顺序是 .MYD 文件。但是 DELETEs 留下缺口, UPDATEs 把缝隙弄乱 INSERTs 喜欢填补空白而不是附加到文件。因此,行顺序相当不可预测。 ALTER TABLE x ORDER BY y 临时设置 .MYD 秩序;此“功能”不适用于innodb。

hfyxw5xn

hfyxw5xn2#

没有明确的 ORDER BY ,当前版本的innodb按其读取的索引的顺序返回行。哪个索引不同,但它总是从某个索引中读取。即使是从“表”中读取数据也是一个索引,它是主键索引。
正如上面的评论,不能保证在下一个版本的innodb中保持不变。你应该把它当作一种巧合,它没有被记录在案,mysql的制作者也没有承诺不改变它。
即使它们的实现没有改变,按索引顺序读取也会导致一些奇怪的效果,这可能是您所预料不到的,并且不会给您提供对您有意义的查询结果集。
例如,默认索引是聚集索引primary。这意味着索引顺序与主键中值的顺序相同(而不是插入它们的顺序)。

mysql> create table mytable ( id int primary key, name varchar(20));

mysql> insert into mytable values (3, 'Hermione'), (2, 'Ron'), (1, 'Harry');

mysql> select * from mytable;
+----+----------+
| id | name     |
+----+----------+
|  1 | Harry    |
|  2 | Ron      |
|  3 | Hermione |
+----+----------+

但是,如果您的查询使用另一个索引来读取表,例如,如果您只访问辅助索引的列,那么您将按以下顺序获得行:

mysql> alter table mytable add key (name);

mysql> select name from mytable;
+----------+
| name     |
+----------+
| Harry    |
| Hermione |
| Ron      |
+----------+

这表明它正在通过对上的二级索引进行索引扫描来读取表 name :

mysql> explain select name from mytable;
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table   | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | mytable | index | NULL          | name | 83      | NULL |    3 | Using index |
+----+-------------+---------+-------+---------------+------+---------+------+------+-------------+

在一个更复杂的查询中,预测innodb将为给定的查询使用哪个索引会变得非常棘手。这种选择甚至可以随着数据的变化而日复一日地改变。
所有这些都表明:你应该使用 ORDER BY 如果你关心你的查询结果集的顺序!

相关问题