Rails 3:合并范围的问题

时间:2015-07-08 14:10:04

标签: mysql ruby-on-rails rails-activerecord

数据库:MySQL

以下是添加的范围,

default_scope where("current = ? AND archived_at IS NULL", true)

scope :expirables,
  -> { where("expiry_date IS NOT NULL") }
scope :ready_to_expire,
  -> { expirables.where(expiry_date: (1.months.ago..Date.today)) }
scope :expired,
  -> { expirables.where("DATE(expiry_date) < ?", Date.today) }

结果查询生成如下,

Document.expirables

SELECT documents.* FROM documents WHERE (documents.current = 1 AND documents.archived_at IS NULL) AND (expiry_date IS NOT NULL)

Document.ready_to_expire

SELECT documents.* FROM documents WHERE documents. {EXPIRY_DATE {1}}

Document.expired

BETWEEN '2015-06-08 13:03:40' AND '2015-07-08' AND (current = 1 AND archived_at IS NULL) AND (expiry_date IS NOT NULL)

请注意SELECT documents.* FROM documents WHERE (current = 1 AND archived_at IS NULL) AND (expiry_date IS NOT NULL) AND (DATE(expiry_date) < '2015-07-08')在第二和第三个查询字符串中的位置。我希望在其他条件之前加上这个。但它会在两种情况下生成不同的查询。

注意(expiry_date IS NOT NULL),此条件是模型中的(current = 1 AND archived_at IS NULL)

我很困惑为什么default_scope范围首先附加在一个案例中,最后一个附加在另一个案例中。并且它还会在检查日期范围时产生问题,而不管它们是否为expirables

是否有解决此问题的解决方法。提前谢谢!

1 个答案:

答案 0 :(得分:0)

如果mysql查询优化引擎关心条件子句的顺序,我会非常惊讶;你是explain两种方式看到了吗?

https://dev.mysql.com/doc/refman/5.0/en/using-explain.html

Mysql在优化is null条件方面受到限制,因此检查expiry_datearchived_at的查询可能不会同时优化:

https://dev.mysql.com/doc/refman/5.5/en/is-null-optimization.html