Скорость доступа к базе данных - PullRequest
0 голосов
/ 14 октября 2018

У меня есть простое приложение (бот Telegram), которым сейчас пользуются около 2000-3000 человек.

Так что я хочу увеличивать баланс пользователей каждые "N" секунд.Это зависит от их текущего статуса.Код работает нормально, но функция может не работать через некоторое время.Я начал с 30 секунд, но после первого выпуска я подумал, что 30 секунд недостаточно, чтобы пройти все строки и выполнить его.Так что сейчас я запускаю его с 1200 секундами, но в любом случае он перестает расти через некоторое время.

Так это только из-за этого или я что-то не так делаю в самом коде?

PS Я использую Python3 и SQLite, и бот постоянно работает на дешевом, слабомVPS сервер.

def balance_growth():
    try:
        cursor = connMembers.cursor()
        sql = "SELECT * FROM members"
        cursor.execute(sql)
        data = cursor.fetchall()
        for single_data in data:
            if single_data[5] == "Basic":
                sql = "UPDATE members SET balance = {B} + 1 WHERE chat_id = {I}".format(B=single_data[1], I=single_data[0])
                cursor.execute(sql)
            elif single_data[5] == "Bronze":
                sql = "UPDATE members SET balance = {B} + 2 WHERE chat_id = {I}".format(B=single_data[1], I=single_data[0])
                cursor.execute(sql)
            elif single_data[5] == "Silver":
                sql = "UPDATE members SET balance = {B} + 12 WHERE chat_id = {I}".format(B=single_data[1], I=single_data[0])
                cursor.execute(sql)
            elif single_data[5] == "Gold":
                sql = "UPDATE members SET balance = {B} + 121 WHERE chat_id = {I}".format(B=single_data[1], I=single_data[0])
                cursor.execute(sql)
            elif single_data[5] == "Platinum":
                sql = "UPDATE members SET balance = {B} + 1501 WHERE chat_id = {I}".format(B=single_data[1], I=single_data[0])
                cursor.execute(sql)

                cursor.execute(sql)
            connMembers.commit()
        cursor.close()

        t = threading.Timer(120, balance_growth).start()
    except Exception as err:
        print(err)

Ответы [ 2 ]

0 голосов
/ 14 октября 2018

Проблема в том, что вы вызываете commit() после каждого отдельного оператора UPDATE, что вынуждает базу данных записывать все изменения из своего кэша.

Выполните один коммит после того, как вы все закончили.

0 голосов
/ 14 октября 2018

Почему бы просто не сделать все это в одном операторе обновления вместо одного в строке?Что-то вроде

UPDATE members SET balance = balance + (CASE whatever_column
                                        WHEN "Platinum" THEN 1501
                                        WHEN "Gold" THEN 121
                                        WHEN "Silver" THEN 12
                                        WHEN "Bronze" THEN 2
                                        ELSE 1 END)

Редактировать:

Другие предложения:

  • Используйте целые числа вместо строк для разных уровней, которые будут быстрее сравнивать и приниматьзанимает меньше места в базе данных.
  • Перепроектируйте свою логику, чтобы не требовалось обновление каждый тик.Может быть, что-то вроде отслеживания последнего обновления баланса строки и его обновления в соответствии с разницей во времени между тогда и сейчас, когда вам нужно проверить баланс.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...