Rails + UUID + Стремительная загрузка - PullRequest
1 голос
/ 16 декабря 2011

У меня есть две модели в приложении rails, одна с первичным ключом UUID:

class User < ActiveRecord::Base
  belongs_to :country, :foreign_key => 'country_uuid'
end

class Country < ActiveRecord::Base
  set_primary_key :uuid
  has_many :users
end

Когда я пытаюсь что-то подобное:

<% @user = User.find :first, :include => [:country] %>
<%= @user.country.name %>

У меня хороший результат,но я вижу 2 запроса в файле журнала.Почему активная загрузка не работает, когда мы меняем ключ идентификатора для ключа UUID?

User Load (0.4ms)  SELECT `users`.* FROM `users` LIMIT 1
Country Load (0.4ms)  SELECT `countries`.* FROM `countries` WHERE (`countries`.`uuid` = '1')

И у меня будет что-то вроде:

User Load (0.4ms)  SELECT `users`.* FROM `users` INNER JOIN countries ON countries.uuid = users.country_uuid LIMIT 1

Есть ли обходной путь?Если я изменю ключ uuid на ключ id, но сохраню формат строки для хранения uuid, все будет в порядке?

Спасибо,

1 Ответ

3 голосов
/ 16 декабря 2011

Используйте соединения вместо include для получения внутреннего соединения

включает в себя всегда выдает второй запрос, но не n + 1 запросов (ленивый)

для направления пользователя -> 1 страна, это не так важно

но если вы едете в другом направлении страны -> много пользователей

country = Country.first
# => select countries.* from countries where id = xxxx limit 1;
country.users.each do 
    # select users.* from users where user_id = xxxx;
    # this could be bad because of lazy loading, one query per iteration
end

# vs...
country = Country.first.includes(:users)
# => select countries.* from countries where id = xxxx limit 1;
# => select users.* from users where country_uuid IN (xxxx);
country.users.each do
    # users are all in memory
end

см. http://guides.rubyonrails.org/active_record_querying.html для получения дополнительной информации

Не думаю, что тот факт, что вы используете UUID, имеет какое-то значение

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...