MySQL中JOIN/LEFT JOIN是否保证原生行序?如何保留Count表行序?
问题描述
MySQL版本
mysql> select version(); +-------------------------+ | version() | +-------------------------+ | 8.0.35-0ubuntu0.22.04.1 | +-------------------------+ 1 row in set (0.00 sec)
表结构
Count表
Count +----------+-------+ | fruit | count | +----------+-------+ | apple | 1 | | pinapple | 1 | | pear | 1 | | grava | 1 | +----------+-------+
Price表
Price +----------+-------+ | fruit | price | +----------+-------+ | pinapple | 20 | | apple | 10 | | pear | 15 | | grava | 5 | +----------+-------+
疑问
- 执行语句
select * from Count c join Price p on c.fruit = p.fruit;返回的行序是否会保证与Count表原生顺序(apple->pinapple->pear->grava)一致,还是与Price表原生顺序(pinapple->apple->pear->grava)一致? - 不想使用
order by fruit,希望保留Count表的原生行序。由于两张表数据完全重叠,可使用LEFT JOIN或RIGHT JOIN查询,是否有方法能保证结果行序与Count表一致?
解答
JOIN后的默认行序说明
MySQL 8.0版本不会保证JOIN操作的结果行序与任何一张源表的原生顺序一致。数据库查询优化器会根据索引、连接算法(嵌套循环、哈希连接、合并连接等)自行决定数据的读取和返回顺序,当前测试结果若与某张表顺序一致,仅为巧合,后续数据变更、索引调整或配置修改都可能改变该顺序。保留Count表原生行序的可行方案
数据库表本身是无序集合,所谓"原生行序"本质是数据插入时的物理存储顺序,但该顺序无可靠内置标识,必须通过额外字段来锁定顺序:
- 给Count表添加自增主键以记录插入顺序:
该ALTER TABLE Count ADD COLUMN id INT AUTO_INCREMENT PRIMARY KEY;id列会严格按照数据插入顺序赋值,对应你需要的"原生行序"。 - 执行JOIN查询时通过自增列排序:
这样就能确保结果行序与Count表的插入顺序完全一致。SELECT c.*, p.price FROM Count c JOIN Price p ON c.fruit = p.fruit ORDER BY c.id;
若不修改表结构,没有任何可靠方法能保证JOIN结果的行序与Count表原生顺序一致——数据库不维护该顺序的元数据,依赖物理存储顺序不可靠,OPTIMIZE TABLE、数据页重组等操作都可能改变物理顺序。
内容的提问来源于stack exchange,提问作者Metal Slime
相关产品推荐
相关产品推荐

