在我的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元素中的顺序不同?
更新:
也许它不是关于map
和pluck
,因为我直接在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吗
答案 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可以自由选择它最好的东西(最便宜的计划和其他内容隐藏在那里)。