MySQL 返回的查询结果是半随机的/排序不一致

MySQL query results returned are semi-random / inconsistently ordered

我正在使用使用 proxysql 的 ndb 集群设置。有4台mysql台服务器,4个数据节点,2个管理节点。当我直接访问其中一个 mysql 服务器时会发生以下情况,因此我认为我可以安全地排除 proxysql 作为根本原因,但除此之外我就迷路了。

这是我设置的 table 来帮助说明我的问题:

mysql> describe delain;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| album_id | tinyint(2)  | NO   | PRI | NULL    | auto_increment |
| album    | varchar(30) | YES  |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

它包含以下数据;请注意,我指定了一个 order by 子句:

mysql> select * from delain order by album_id;
+----------+-------------------------+
| album_id | album                   |
+----------+-------------------------+
|        1 | Lucidity                |
|        2 | April Rain              |
|        3 | We Are the Others       |
|        4 | The Human Contradiction |
|        5 | Moonbathers             |
+----------+-------------------------+
5 rows in set (0.00 sec)

如果我不指定顺序子句,返回的结果似乎是随机的,例如:

mysql> select * from delain;
+----------+-------------------------+
| album_id | album                   |
+----------+-------------------------+
|        3 | We Are the Others       |
|        5 | Moonbathers             |
|        1 | Lucidity                |
|        2 | April Rain              |
|        4 | The Human Contradiction |
+----------+-------------------------+
5 rows in set (0.00 sec)

当我重复查询(无顺序子句)时,我几乎每次都得到不同的顺序。它似乎并不是真正随机的,但对我来说确实没有任何可辨别的模式。

为什么会这样?我对 mysql 的经验一直是默认排序基本上是根据主键,但这也是我第一次特别使用 ndb 集群;我不知道那里是否存在差异,或者配置文件中是否有遗漏的设置或其他什么。非常感谢任何帮助!

这是标准的 SQL 行为。

https://mariadb.com/kb/en/library/sql-99/order-by-clause/ 部分表示:

An ORDER BY clause may optionally appear after a query expression: it specifies the order rows should have when returned from that query (if you omit the clause, your DBMS will return the rows in some random order).

(强调我的)

更准确的说法是它将return行任意顺序,而不是随机顺序。随机表示顺序将从一次执行更改为下一次执行。

  • 在 InnoDB 的情况下,顺序往往是访问行的索引顺序。它读取的索引不一定是主键。因此,如果您对内部结构有所了解,那么顺序是不变的并且有点预测table。但这不是随机的。

  • 在 MyISAM 的情况下,顺序往往是行存储在 table 中的顺序删除行后插入时文件中 space 的位置。

  • 就 NDB 而言,我不太了解它的内部结构,所以我无法描述它对 "default" 顺序的规则,但如果没有显式 ORDER BY,允许存储引擎以任意顺序 return 行。

对于 NDB,顺序取决于时间 SELECT * 来自 table;

SELECT * 来自 table 被实现为并行化 在数据节点及其数据库中进行全面 table 扫描 线程与一个 MySQL 个线程正在接收结果。

因此,使用过滤后的查询,例如 SELECT * 来自 table 其中 filter_column = 2; 过滤器在许多线程中并行评估。 这些线程中的每一个 return 行到任何 MySQL 线程 顺序取决于 OS 调度程序、网络和许多 其他事情。所以没有默认顺序,除非你 使用 ORDER BY.

所以对于 NDB 来说,顺序是真正随机的,而不仅仅是任意的。 您会在所有使用 MTR 的 NDB 测试套件中看到这一点 查询主要使用 SELECT * from table ORDER BY some_field;