В качестве предупреждения, это для школьного проекта с другими школьными товарищами по команде, поэтому мой вопрос только ради изучения лучших практик. Мы создаем веб-приложение системы рекомендаций, которое в настоящее время состоит из 3 сервисов (интерфейсный интерфейс, сервер Flask, база данных postgres), где используемая нами база данных представляет собой простую базу данных «многие ко многим» с тремя таблицами (таблица пользователей, соединительная таблица, таблица элементов). В соединительной таблице 42 миллиона строк и 2 столбца, в таблице User — 1 миллион строк и 2 столбца, а в таблице Item — 2,3 миллиона строк и 14 столбцов. У нас есть несколько различных алгоритмов совместной и контентной фильтрации, с которыми мы работаем. Два разных метода:
Эти методы легко реализовать, но время запроса может быть очень медленным, особенно для метода 1, поскольку он требует запроса таблицы из 42 миллионов записей. Я ищу рекомендации по увеличению отклика веб-приложения до чего-то разумного (менее 5 секунд) для каждого из этих методов. Одним из самых простых вариантов реализации будет загрузка таблицы Item в Pandas DataFrame при запуске и использование ее в качестве своего рода кеша на диске, но это кажется неправильным и, конечно, не масштабируемым. Существуют ли другие методы, которые используются чаще? Я совсем не знаком с базами данных в памяти, такими как Redis, но поможет ли что-то подобное в ускорении, которое мне нужно?
Я не эксперт по базам данных, но есть довольно общий подход к вопросам производительности, который часто применим. Обычно они применяются по порядку, т. е. использование оборудования для решения проблемы может не сильно помочь без соответствующих индексов.
Часть этого состоит в том, чтобы установить базовый уровень, чтобы иметь хорошее представление о том, принесло ли изменение пользу или нет. Другая часть — профилирование для выявления потенциальных проблем с производительностью. Для баз данных это обычно включает некоторый способ проверки и профилирования запросов. Этот вопрос касается профайлера запросов postgres
Обычно это включает в себя более разумные способы сделать это, уменьшая вычислительную сложность проблемы. Что касается баз данных, это обычно включает в себя обеспечение того, чтобы таблицы имели соответствующие индексы, избегая необходимости сканирования целых таблиц. Другой довольно распространенной проблемой является фильтрация в приложении, а не в базе данных, что может привести к дополнительным задержкам, поскольку необходимо передать больше записей.
Если вы делаете что-то неоднократно, может иметь смысл сохранить результаты на случай, если они потребуются снова. Что касается веб-сайтов и баз данных, это может быть просто внешний интерфейс, который выполняет некоторое кэширование, или это может быть что-то вроде материализованного представления, где больше работы выполняется заранее, чтобы уменьшить работу, необходимую для каждого запроса. Для всех систем кэширования вам потребуется некоторая политика аннулирования кэша, и это одна из потенциально сложных проблем в вычислениях. Но для рекомендательной системы может быть достаточно просто обновлять кеш каждый день или около того.
Если всего остального недостаточно, вы часто можете использовать аппаратное обеспечение для решения проблемы, то есть больше памяти, более быстрые диски, больше процессоров и т. д. Если одной машины недостаточно, postgres и многие другие базы данных поддерживают сегментирование, но, вероятно, будут работать лучше, когда существует некоторое разделение, так что запросам нужен доступ только к данным в одном сегменте, поэтому в вашем случае это может быть неприменимо.
Для некоторых высокопроизводительных систем может иметь смысл написать собственное специализированное решение. Такие системы, как базы данных, должны хорошо справляться с широким кругом задач. Для некоторых задач пользовательское решение может привести к значительному повышению производительности, поскольку это может сделать многие предположения невозможными для более общей системы.