我正在使用DataMapper(ruby gem)作为mysql数据库的ORM。 (dm-core 1.1.0,do-mysql-adapter 1.1.0,do_mysql 0.10.6)
我正在编写一个包含两个表的应用程序:一段时间内磁盘使用情况的日志,以及一个“当前用法”表,其中包含具有“最新”磁盘使用情况的外键,以便于参考。 DataMapper类是Quota
和LatestQuota
,具有简单的架构:
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需要进行查询。有什么办法强迫它做我想做的事吗?我的关系错了吗?我查错了吗?
答案 0 :(得分:6)
由于某种原因,嵌套哈希样式的查询将始终执行子选择。要强制INNER JOIN,请使用字符串查询路径:LatestQuota.all('quota.percentage.gte'=> threshold)