【问题标题】:MySQL limit 1 returns the last record of result set of order by?MySQL limit 1 返回order by的结果集的最后一条记录?
【发布时间】:2015-10-13 10:07:26
【问题描述】:

1.我创建一个表

create table sort (
 a int,
 b int,
primary key (a));

2.然后我插入了三条记录

insert into sort values(1, 10), (2, 10), (3, 10);

3.当我选择使用这个sql

select * from sort order by b;

它给出了这样的结果

+---+------+
| a | b    |
+---+------+
| 1 |   10 |
| 2 |   10 |
| 3 |   10 |
+---+------+
  1. 当我选择表时使用这个查询

    select * from sort order by b limit 1;

结果集是这样的

+---+------+
| a | b    |
+---+------+
| 3 |   10 |
+---+------+

这不是我例外的(我认为返回第一条记录是合理的)。

我的 mysql 版本是 Ver 14.14 Distrib 5.6.23,适用于 osx10.8 (x86_64)

谁能给我解释一下?谢谢。

【问题讨论】:

  • 为什么要返回第一个?您按“B”列排序,“A”列无关紧要,MySQL 将数据存储在文件中的方式与您在 GUI 中看到的方式不同,它对表进行排序并获取具有最低“B”值的列,是否有任何带有较低“B”的行?不,这意味着查询是正确的,如果要返回第一行,则按b,a添加顺序
  • 有趣。我尝试了它(使用 innodb 和 myisam,以防有所不同),并得到第一行 (a=1) 作为限制 1 的结果(如您所料)。
  • @ogres 将其添加为答案
  • 这仍然不是一个解释。当然,mysql 返回 3 行中的任何一行都没有问题,但我更喜欢对行为的实际解释。我试图复制它,但我不能。
  • 你期待这个order by b asc or desc

标签: mysql limit


【解决方案1】:

这是因为当您输入 select * from sort order by b; 时,这将加载隐藏字段 ACS。这意味着以升序查询加载所有日期

+---+------+
| a |   b  |
+---+------+
| 1 |  10  |
| 2 |  10  |
| 3 |  10  |
+---+------+

但是,如果您使用select * from sort order by b limit 1;,它会再次使用ACS 加载数据,然后您就拥有LIMIT 1 的条件。所以在b 列中都是10,所以它会加载最后一个添加的值。

Bz MySQL 将决定最后添加的行是最新的行

【讨论】:

    【解决方案2】:

    我实际上无法解释这种行为,因为我无法复制它。但我可以证明 OP 所期望的是我的 mysql ( Ver 14.14 Distrib 5.5.44, for debian-linux-gnu (i686)) 如何工作 [注意,我以不同的顺序插入记录,以证明一点):

    首先,没有主键:

    mysql> create table sort (
        ->  a int,
        ->  b int);
    mysql> insert into sort values (3,10),(2,10), (1,10);
    mysql> select * from sort order by b limit 1;
    +------+------+
    | a    | b    |
    +------+------+
    |    3 |   10 |
    +------+------+
    

    显示第一条插入的记录

    还有一个主键:

    mysql> create table sort (
        ->  a int,
        ->  b int,
        -> primary key (a));
    mysql> insert into sort values (3,10),(2,10), (1,10);
    mysql> select * from sort order by b limit 1;
    +---+------+
    | a | b    |
    +---+------+
    | 1 |   10 |
    +---+------+
    

    这是一个 myisam 表(我的服务器上的默认),因此该表有一个聚集索引,这会导致该表按 a 列的顺序读取。因此,a=1 是第一条记录(我相信)。

    最后,使用innodb:

    mysql> create table sort (  a int,  b int, primary key (a) ) engine=myisam;
    mysql> insert into sort values (3,10),(2,10), (1,10);
    mysql> select * from sort order by b limit 1;
    +---+------+
    | a | b    |
    +---+------+
    | 3 |   10 |
    +---+------+
    

    没有聚集索引,所以返回输入的第一条记录。

    这些都不能解释 OP 声称的内容,但我无法让它发生。

    【讨论】:

    • innodb表的主键不是聚集索引?
    • myisam 表的主键不是聚集索引。这就是 myisam 和 innodb 示例不同的原因(我认为)。
    【解决方案3】:

    这个 SQL Server 已经返回了合理的记录。 因为,您按数量相同的列排序(按服务评估)。

    SQL Server 执行的步骤是::

    检查它是否有索引 -> 从磁盘/索引读取表 -> 排序数据 -> 获取 n 个排序数据。

    (来自您的查询)

    因此,此 SQL Server 将从磁盘(存储)返回它在主表中找到的第一个,因为您还没有索引它。



    除非您按 a,b 订购。
    您将获得 1,10 作为结果。

    或者创建一个索引,使您的数据顺序不同。 (您也可以获得 2,10 作为结果)
    否则,您将把第一个插入的数据作为结果存入磁盘。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-05
      • 2018-01-26
      相关资源
      最近更新 更多