mysql中空列之间的顺序是什么?

时间:2015-05-25 10:58:55

标签: mysql ruby-on-rails

在我的rails 3应用程序中,有一个名为Book的模型,

Book(id: integer, link_index: integer, publish_status: integer, link_page: integer, created_at: datetime, updated_at: datetime)
当我查询时,

link_index 被允许为NULL ,其他人不允许为NULL:

Book.where(link_page: 1).published.order('link_index DESC').limit(5).pluck(:id)

返回[518, 331, 486, 488, 493]

但是当我使用map代替pluck时,

Book.where(link_page: 1).published.order('link_index DESC').limit(5).map(&:id)

返回[518, 512, 516, 534, 566]

我们所知道的是:只有id = 518的列有link_index = 4,所有其他列'link_index是NULL。所以结果是正确的:518作为第一个元素返回。

但是在上述两种方式中,为什么NULL元素中的顺序不同?

更新:

也许它不是关于mappluck,因为我直接在mysql shell中使用SQL,它始终是同一个问题:

SELECT id FROM `books` WHERE `books`.`link_page` = 1 AND `books`.`publish_status` = 4 ORDER BY link_index DESC LIMIT 5;

返回:

+-----+
| id  |
+-----+
| 518 |
| 331 |
| 486 |
| 488 |
| 493 |
+-----+

但是

SELECT * FROM `books` WHERE `books`.`link_page` = 1 AND `books`.`publish_status` = 4 ORDER BY link_index DESC LIMIT 5;

返回:

+-----+------------+----------------+-----------+
| id  | link_index | publish_status | link_page |  
+-----+------------+----------------+-----------+
| 518 |          4 |              4 |         1 |
| 512 |       NULL |              4 |         1 |
| 516 |       NULL |              4 |         1 |
| 534 |       NULL |              4 |         1 |
| 566 |       NULL |              4 |         1 |
+-----+------------+----------------+-----------+

WHY吗

2 个答案:

答案 0 :(得分:0)

map和pluck是完全不同的功能。 地图在收集级别上运行,其中 pluck 在数据库级别上运行。

http://guides.rubyonrails.org/active_record_querying.html#pluck

答案 1 :(得分:0)

我建议你查看这两个中的MySQL EXPLAIN。区别在于用于检索数据的索引或某些临时表的使用。第一个查询只返回ID,因此可以使用正确索引上的索引扫描或索引合并来获取这些ID,然后顺序取决于这些ID的BTREE顺序。在第二个的情况下,计划将是不同的,使用可能不同的索引集或它们的不同顺序,因此它以其他顺序选择行 - 并且如果许多值为NULL,则不存在“正确”的顺序(你做了)没有定义第二列,以便在重复link_index的情况下使用)并且mysql可以自由选择它最好的东西(最便宜的计划和其他内容隐藏在那里)。