MySQL datamapper适配器链接查询而不是加入

时间:2011-07-15 21:19:41

标签: mysql ruby datamapper

我正在使用DataMapper(ruby gem)作为mysql数据库的ORM。 (dm-core 1.1.0,do-mysql-adapter 1.1.0,do_mysql 0.10.6)

我正在编写一个包含两个表的应用程序:一段时间内磁盘使用情况的日志,以及一个“当前用法”表,其中包含具有“最新”磁盘使用情况的外键,以便于参考。 DataMapper类是QuotaLatestQuota,具有简单的架构:

class Quota
  include DataMapper::Resource

  property :unique_id, Serial, :key => true
  property :percentage, Integer
  ... (more properties)
end

class LatestQuota
  include DataMapper::Resource
  belongs_to :quota, :key => true
end

在我的代码中,我想查找LatestQuota表中与百分比高于95的配额相对应的所有条目。我正在使用以下datamapper查询:

quotas = LatestQuota.all(:quota => {:percentage.gte => threshold})
...later...
quotas.select{|q| some_boolean_function?(q)}

而some_boolean_function是以DataMapper无法知道的方式过滤掉结果的东西,因此我需要调用ruby的select()。

但它最终会调用以下SQL查询(从DM的调试输出报告:)

SELECT `unique_id` FROM `quota` WHERE `percentage` >= 95

然后:

SELECT `quota_unique_id` FROM `latest_quota` 
WHERE `quota_unique_id` IN (52, 78, 82, 232, 313, 320…. all the unique id's from the above query...)

这是一个荒谬的次优查询,所以我认为我做错了。 quota表中包含数百万条记录(历史数据)与latest_quota中的15k左右记录,首先选择所有quota条记录,然后选择latest_quota条记录结果完全是错误的做法。

我希望它能做的事情是:

SELECT q.* from quota q
INNER JOIN latest_quota lq
ON lq.quota_unique_id=q.unique_id
WHERE q.percentage >= 95;

使用我当前的数据需要0.01秒,而不是5分钟左右,DataMapper需要进行查询。有什么办法强迫它做我想做的事吗?我的关系错了吗?我查错了吗?

1 个答案:

答案 0 :(得分:6)

由于某种原因,嵌套哈希样式的查询将始终执行子选择。要强制INNER JOIN,请使用字符串查询路径:LatestQuota.all('quota.percentage.gte'=> threshold)