Rails pg 生产中偏移量查询的问题

Rails pg issues with offset query on production

以下语句产生问题:

Lang.limit(10).offset(0)

在我的开发环境中 rails 控制台产生以下结果:

2.1.1 :001 > Lang.limit(10).offset(0)
  Lang Load (1.2ms)  SELECT "langs".* FROM "langs" LIMIT 10 OFFSET 0
 => [#<Lang id: 1, english: "be", english_to_spanish: "ser", spanish: "una", spanish_to_english: "a", created_at: "2015-01-03 20:30:35", updated_at: "2015-01-03 20:30:35">, #<Lang id: 2, english: "I", english_to_spanish: "Yo", spanish: "no", spanish_to_english: "do not", created_at: "2015-01-03 20:30:35", updated_at: "2015-01-03 20:30:35">, #<Lang id: 3, english: "you", english_to_spanish: "usted", spanish: "pero", spanish_to_english: "but", created_at: "2015-01-03 20:30:35", updated_at: "2015-01-03 20:30:35">, #<Lang id: 4, english: "with", english_to_spanish: "con", spanish: "la", spanish_to_english: "the", created_at: "2015-01-03 20:30:35", updated_at: "2015-01-03 20:30:35">, #<Lang id: 5, english: "the", english_to_spanish: "la", spanish: "que", spanish_to_english: "that", created_at: "2015-01-03 20:30:35", updated_at: "2015-01-03 20:30:35">, #<Lang id: 6, english: "they", english_to_spanish: "ellos", spanish: "y", spanish_to_english: "and", created_at: "2015-01-03 20:30:35", updated_at: "2015-01-03 20:30:35">, #<Lang id: 7, english: "that", english_to_spanish: "que", spanish: "por", spanish_to_english: "by", created_at: "2015-01-03 20:30:35", updated_at: "2015-01-03 20:30:35">, #<Lang id: 8, english: "this", english_to_spanish: "este", spanish: "lo", spanish_to_english: "it", created_at: "2015-01-03 20:30:35", updated_at: "2015-01-03 20:30:35">, #<Lang id: 9, english: "are", english_to_spanish: "son", spanish: "se", spanish_to_english: "is", created_at: "2015-01-03 20:30:35", updated_at: "2015-01-03 20:30:35">, #<Lang id: 10, english: "a", english_to_spanish: "un", spanish: "con", spanish_to_english: "with", created_at: "2015-01-03 20:30:35", updated_at: "2015-01-03 20:30:35">] 
2.1.1 :002 > 

在我的生产环境中 rails 控制台产生以下结果:

irb(main):002:0> Lang.limit(10).offset(0)
  Lang Load (2.4ms)  SELECT "langs".* FROM "langs" LIMIT 10 OFFSET 0
=> [#<Lang id: 4172, english: "judicial", english_to_spanish: "judicial", spanish: "habitaciones", spanish_to_english: "room", created_at: "2015-01-03 20:28:01", updated_at: "2015-01-03 20:28:01">, #<Lang id: 4173, english: "diamond", english_to_spanish: "diamante", spanish: "afortunadamente", spanish_to_english: "fortunately", created_at: "2015-01-03 20:28:01", updated_at: "2015-01-03 20:28:01">, #<Lang id: 4174, english: "alternatives", english_to_spanish: "alternativas", spanish: "detener", spanish_to_english: "stop", created_at: "2015-01-03 20:28:01", updated_at: "2015-01-03 20:28:01">, #<Lang id: 4175, english: "sighed", english_to_spanish: "suspirado", spanish: "antecedentes", spanish_to_english: "background", created_at: "2015-01-03 20:28:01", updated_at: "2015-01-03 20:28:01">, #<Lang id: 4176, english: "surveys", english_to_spanish: "encuestas", spanish: "historiador", spanish_to_english: "historian", created_at: "2015-01-03 20:28:01", updated_at: "2015-01-03 20:28:01">, #<Lang id: 4177, english: "managing", english_to_spanish: "gerente", spanish: "sobrevivir", spanish_to_english: "survive", created_at: "2015-01-03 20:28:01", updated_at: "2015-01-03 20:28:01">, #<Lang id: 4178, english: "bottles", english_to_spanish: "botellas", spanish: "salvación", spanish_to_english: "salvation", created_at: "2015-01-03 20:28:01", updated_at: "2015-01-03 20:28:01">, #<Lang id: 4179, english: "productive", english_to_spanish: "productivo", spanish: "renuncia", spanish_to_english: "resignation", created_at: "2015-01-03 20:28:01", updated_at: "2015-01-03 20:28:01">, #<Lang id: 4180, english: "quarters", english_to_spanish: "cuarteles", spanish: "saliendo", spanish_to_english: "leaving", created_at: "2015-01-03 20:28:01", updated_at: "2015-01-03 20:28:01">, #<Lang id: 4181, english: "arrangement", english_to_spanish: "disposición", spanish: "persecución", spanish_to_english: "persecution", created_at: "2015-01-03 20:28:01", updated_at: "2015-01-03 20:28:01">]
irb(main):003:0>

从开发中可以看出,这会生成 Lang ID 的 1..10,但在生产中会生成 Lang ID 的 4172..4181。关于为什么存在差异以及如何使生产环境表现得像开发环境的任何想法?

如果您没有在 SQL 中指定特定的顺序,您将按照数据库想要的任何顺序获取行,而这很少是您想要的顺序。所以,如果你想要按特定顺序排列的东西,请这样说:

Lang.order(:id).offset(0).limit(10)
# ---^^^^^^^^^^

这会在 SQL 中添加一个 ORDER BY 子句,并以预期的顺序为您提供内容。

你在你的开发环境中得到有序的东西纯粹是偶然的,不能保证你明天或下周在做了一些插入、删除和更新之后就可以按那个顺序得到它们。