2011-01-24 3 views
1

Этот код должен обновить всю таблицу путем применения фильтра к его «имя» значений:Рубин на Rails ActiveRecord эффективность

entries = select('id, name').all 
entries.each do |entry| 
    puts entry.id 
    update(entry.id, { :name => sanitize(entry.name) }) 
end 

Я довольно новыми для Ruby On Rails и нашел его интересным, что мой запрос выбора разделяется на отдельные выбора строки:

SELECT `entries`.* FROM `entries` WHERE (`entries`.`id` = 1) LIMIT 1 
SELECT `entries`.* FROM `entries` WHERE (`entries`.`id` = 2) LIMIT 1 
SELECT `entries`.* FROM `entries` WHERE (`entries`.`id` = 3) LIMIT 1 
... 

Как я понимаю, это своего рода оптимизация, обеспечивается Rails - выбрать строку только тогда, когда это необходимо (каждый цикл), а не все записи сразу.

Однако, это действительно более эффективно в этом случае? Я имею в виду, если у меня есть 1000 записей в моей таблице базы данных - лучше ли делать 1000 запросов, чем один? Если нет, как я могу заставить Rails выбрать более одной строки для каждого запроса?

Другой вопрос: не все строки обновляются этим запросом. Rails игнорирует запрос на обновление, если предоставленные значения являются такими же, какие уже существуют (другими словами, если entry.name == sanitize (entry.name))?

ответ

1
Entry.find_each do |entry| 
    #... 
end 

Эта информация берет все записи (100 за запрос) и предоставляет каждую запись для вашего удовольствия.

Если атрибуты не изменены, Rails не будет выполнять запрос UPDATE.

2

ActiveRecord - это уровень абстракции, но при выполнении определенных операций (особенно с использованием больших наборов данных) полезно знать, что происходит под слоем абстракции.

Это в значительной степени относится ко всем абстракциям. (См классической статьи Джоэл Спольский на дырявых абстракциях: http://www.joelonsoftware.com/articles/LeakyAbstractions.html)

Для рассмотрения дела в точке здесь, Rails предоставляет метод update_all

Смежные вопросы