Я использую DataMapper (гем ruby) в качестве ORM для базы данных mysql. (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
содержатся миллионы записей (исторических данных) по сравнению с примерно 15 000 записей в latest_quota
, и выбор сначала всех 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 для выполнения своего запроса. Есть ли способ заставить его делать то, что я хочу? У меня неправильные отношения? Я неправильно спрашиваю?