У меня есть вопрос об использовании БД / memcached. У меня есть ряд вопросов в базе данных, разделенных по уровням (около 1000 вопросов на уровень). Для каждого пользователя на каждом шаге мне нужно выбрать один вопрос для заданного уровня случайным образом. Я использую стандартный django ORM выбор + случайную строку, используя этот запрос:
question = Question.objects.all().filter(level=1).order_by('?')[0]
После анализа файлов журнала я увидел, что около 50% времени запросов к БД тратится на выбор вопросов. Я пытался использовать memcached для этого. Из-за случайного выбора это не очевидно, я не могу использовать его как хранилище ключ-значение для пар question_id-question. Поэтому я решил разделить вопросы по уровням, сохранить их в memcached, после чего выбрать группу вопросов из memcached и выбрать случайный с использованием python, например:
for level in ...:
questions_by_level = [q for q in questions if q.level == level]
cache.set('questions' + str(level), questions_by_level)
и когда мне нужен вопрос:
questions = cache.get('questions' + str(level))
question = choice(questions)
Я запрограммировал memcached на той же машине, и, таким образом, получаю 1000 вопросов примерно в 2,5 раза медленнее, чем из базы данных. Вероятно, это потому, что из memcached выбрано 1000 объектов, десериализовано в python и выбрано случайное.
Можно ли выбрать другую стратегию использования кеша в этой ситуации? Вопросы обновляются редко, так что неплохо бы иметь кеш с моей точки зрения.
Благодаря.
UPD : одно решение, которое я обнаружил сам. Для каждого вопроса создайте строковый ключ следующим образом: l_n, где l - уровень, а n - номер вопроса в группе вопросов с уровнем l. Теперь, чтобы найти случайный вопрос, я строю случайный ключ:
key = str (level) + '_' + str (int (random.random () * num_of_questions_by_level)
плюсы: получение 1000 случайных вопросов примерно в 10 раз быстрее, чем из БД
минусы: начальное заполнение кэша очень медленное