Помогите мне оптимизировать объект ActiveRecord со слишком многими атрибутами - PullRequest
1 голос
/ 31 августа 2011

Я работаю над приложением, которое связано с устаревшей базой данных. Основная модель основана на тупо большой таблице столбцов 100+. Я не слишком много знаю о внутренней работе ActiveRecord, но мне кажется, что любой запрос в этой модели замедляется, потому что он создает объекты с более чем 100 атрибутами. Давайте назовем это SlowModel.

Рендеринг страниц с этой моделью иногда занимает 17 секунд на моем компьютере разработчика. Прямые запросы MySQL занимают всего ~ 0,5 - 1 секунды.

Мне удалось ускорить одну часть приложения с помощью представления MySQL, которое выбирает подмножество полей (около 20). Мы назовем это QuickModel. Использование представлений в порядке, но не самое портативное решение.

Вероятно, я продолжу пытаться добавить эту QuickModel в другие части сайта, но мне было интересно, есть ли у кого-нибудь другие идеи по ускорению создания оригинального объекта. Например, есть ли способ указать в модели, какие столбцы activerecord следует просто игнорировать и избегать построения? Возможно, существуют определенные типы столбцов (: текст ??), которые вызывают раздувание в объектах ActiveRecord.

Предположим, что столбцы имеют правильные индексы.

Ответы [ 3 ]

5 голосов
/ 31 августа 2011

Вы можете указать, какие столбцы будут возвращены при поиске модели, используя опцию: select поиска ActiveRecord:

SlowModel.all(:select => 'id, col1, col2, col3')

... будет загружать экземпляры SlowModel только с указанными заполненными столбцами.

1 голос
/ 01 сентября 2011

В соответствии с тем, что говорит Winfield, вы можете взглянуть на использование трекера атрибутов, например SlimScrooge .Трекер пытается извлечь только те данные, которые вы используете, что снижает накладные расходы.Он пытается автоматически сделать то, что предлагает Winfield.

Пример из файла Readme:

# 1st request, sql is unchanged but columns accesses are recorded
Brochure Load SlimScrooged 1st time (27.1ms)   SELECT * FROM `brochures` WHERE (expires_at IS NULL)

# 2nd request, only fetch columns that were used the first time
Brochure Load SlimScrooged (4.5ms)   SELECT `brochures`.expires_at,`brochures`.operator_id,`brochures`.id FROM `brochures` WHERE (expires_at IS NULL)

# 2nd request, later in code we need another column which causes a reload of all remaining columns
Brochure Reload SlimScrooged (0.6ms) `brochures`.name,`brochures`.comment,`brochures`.image_height,`brochures`.id, `brochures`.tel,`brochures`.long_comment,`brochures`.image_name,`brochures`.image_width FROM `brochures` WHERE `brochures`.id IN ('5646','5476','4562','3456','4567','7355')

# 3rd request
Brochure Load SlimScrooged (4.5ms)   SELECT `brochures`.expires_at,`brochures`.operator_id,`brochures`.name, `brochures`.id FROM `brochures` WHERE (expires_at IS NULL)
1 голос
/ 31 августа 2011

Как насчет того, чтобы иметь совершенно новую QuickModel, сидящую за собственным столом ... и QuickModel has_one SlowModel?

Вы можете использовать SQL для перемещения наиболее необходимых данных в таблицу QuickModel и ссылаться на SlowModel, используя my_quick_model.slow_model только при необходимости.

В качестве альтернативы, вы можете добавить «select» в область видимости по умолчанию (для более подробной информации вы можете воспользоваться Google «rails default scope»). По умолчанию он выбирает только уменьшенный набор, но вы можете запросить все атрибуты, передав: select => "*", если необходимо.

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