1

Я тестирую производительность сайта путем посева ~ 10 000 записей.Большие результаты Ruby on Rails

Я хочу отобразить их на одной странице вывода.

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

Несколько вопросов:

  1. Как batch найти работу и есть какой-то способ, которым я могу найти эти записи в небольших приращений (в фоновом режиме) на контроллере уровня/модели, а не только путем добавления авто -прокрутка или разбиение на страницы на вид?

  2. Мне не нужны все данные от пользователя, поэтому я также могу использовать .pluck. Так, например, теоретически, возможно, я смогу сделать User.pluck(:date_or_birth), но что, если бы у меня был метод age для User, где user.age вернет целое число возраста, основанное на атрибуте .date_of_birth. Есть ли метод, как легкий, как pluck, который позволяет нам захватывать методы (то есть .pluck_method(:age)). Проблема, которую я имею здесь, заключается в том, что некоторые из того, что я хочу отобразить, не является атрибутом, но могу ли я выщипывать атрибуты и выполнять любые манипуляции с атрибутами как helper?

  3. Если я использую pluck, моя коллекция теперь является array вместо хэша ActiveRecord, лучше ли конвертировать в hash или просто получить доступ к массиву по заказу?

Просто старайтесь сделать несколько разных сайтов как можно быстрее, и, как правило, код работает быстро, но мне нужно, чтобы с ним нужно было масштабировать.

ответ

2

Оказание всех записей на одной странице неизбежно перестанет быть жизнеспособным решением по мере роста вашего набора данных. В конечном итоге вы столкнетесь с ограничениями ресурсов или времени обработки на стороне сервера, а также столкнетесь с ограничениями с веб-клиентами. Конечно, вам нужно будет сделать свое собственное профилирование и бенчмаркинг, чтобы определить, где находится эта граница. До тех пор, вот вещи, которые отвечают на ваш вопрос:

  1. (а) Rails предоставляет .find_each метод на ActiveRecord :: Relation. Он будет обрабатывать большие запросы в меньшие патроны (по 1000 записей по умолчанию), чтобы избежать работы с базой данных и сразу загрузить весь набор данных в память. Ваш запрос может выглядеть так: User.find_each(batch_size: 2000)Read more on find_each here. Также взгляните на find_in_batches на той же странице.

    (b) find_each решает только половину проблемы, поскольку Rails отображает весь просмотр страницы и шаблон в памяти перед отправкой обратно клиенту. ActionController::Streaming предлагает улучшения поэтапно отправлять биты страницы обратно клиенту по мере их рендеринга.

    Потоковая передача инвертирует поток рендеринга путем рендеринга макета и потоковой передачи каждой части макета по мере их обработки. Это позволяет очень быстро передавать заголовок HTML (который обычно находится в макете) обратно клиенту, что позволяет загружать JavaScripts и таблицы стилей раньше, чем обычно.

    Этот подход был введен в Rails 3.1 и по-прежнему улучшается. Несколько промежуточных сред стойки могут не работать, и вам необходимо быть осторожными при потоковой передаче. Эти вопросы будут рассмотрены в ближайшее время.

    Для использования потоковой передачи вам потребуется использовать версию Ruby, которая поддерживает волокна (волокна поддерживаются с версии 1.9.2 основной реализации Ruby).

    (c) Я настоятельно рекомендую вам также взглянуть на некоторые различные методы кеширования, чтобы избежать повторного рендеринга или вообще попасть в базу данных. rails caching guides обеспечивают отличный обзор различных методов, которые могут работать для вашего проекта.

  2. Вы можете использовать select метод вместо pluck, чтобы ограничить данные, извлеченные из базы данных для одного или нескольких столбцов базы данных, которые вас интересуют. Select возвращает набор ActiveRecord так же, как типичный запрос, за исключением только рекомендуемую атрибуты будут заполнены в памяти. С помощью select(:date_of_birth) вы можете использовать свой метод user.age.

  3. select может быть лучшим решением для вас здесь. Одна вещь, которую следует иметь в виду, - создавать экземпляры AR-объектов для каждой записи, увеличит требуемую память и использует дополнительные циклы процессора по сравнению с простым массивом, который вы используете с помощью pluck.