为什么使用 join 和 order by 主表参数 时,无法保证每次查询的数据顺序

数据准备

CREATE TABLE `A` (
  `id` int(32) NOT NULL AUTO_INCREMENT,
  `a` varchar(32) DEFAULT NULL,
  `sort` int(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

CREATE TABLE `B` (
  `id` int(32) NOT NULL AUTO_INCREMENT,
  `a_id` int(32) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;



INSERT INTO `test1`.`A`(`id`, `a`, `sort`) VALUES (1, 'A', 0);
INSERT INTO `test1`.`A`(`id`, `a`, `sort`) VALUES (2, 'B', 0);
INSERT INTO `test1`.`A`(`id`, `a`, `sort`) VALUES (3, 'C', 0);
INSERT INTO `test1`.`A`(`id`, `a`, `sort`) VALUES (4, 'D', 0);


INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (1, 1);
INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (2, 1);
INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (3, 1);
INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (4, 1);
INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (5, 2);
INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (6, 2);
INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (7, 2);
INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (8, 2);
INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (9, 3);
INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (10, 3);
INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (11, 3);
INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (12, 3);
INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (13, 4);
INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (14, 4);
INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (15, 4);
INSERT INTO `test1`.`B`(`id`, `a_id`) VALUES (16, 4);

查询语句

SELECT a.id AS aId , a.a FROM A a LEFT JOIN B b ON a.id = b.a_id ORDER BY a.sort ASC; 

SELECT a.id AS aId FROM A a LEFT JOIN B b ON a.id = b.a_id ORDER BY a.sort ASC;

(不同机器使用相同sql查询结果是不一样的,但这里为了在单机避开mysql的查询缓存,使用查询不同参的形式)

image.png

image.png

问题

为什么两次的查询结果顺序会不一样?建表时,我使用了InnoDB在没有指定顺序时,应该会使用主键id作为默认排序吧。join连表用的是B表的主键索引,索引默认保存的是B+树,B+树也是有序的。问题是出在哪里?

阅读 6.8k
1 个回答

left join后,会默认按照关联主键来排序,但使用了order by就不再使用默认主键排序了,当order by字段的值相同时,Mysql会乱序返回。

MySQL有两种方式可以实现ORDER BY

  • 1.通过索引扫描生成有序的结果
  • 2.使用文件排序(filesort)

具体原因可以参考下面的文章:
https://www.cnblogs.com/lalal...

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题