многопроцессорный доступ к базе данных Python очень медленный - PullRequest
1 голос
/ 18 ноября 2009

У меня есть графический интерфейс, который будет взаимодействовать с базой данных postgres, используя psycopg2. У меня есть подключение БД в многопроцессорном процессе, и отправлять SQL через многопроцессорную очередь, и получать через другую очередь.

Проблема в том, что скорость очень, очень низкая. Простой выбор * из небольшой таблицы (30 строк) может занимать 1/10 секунды или занимать более одной секунды.

Кто-нибудь знает, почему это так медленно?

Новая информация: Он отлично работает на winxp, точно такой же код, поэтому прерывистая задержка происходит только на моем Linux-компьютере (Ubuntu 9.10)

Более подробная информация: после того, как вы выбрали заглушку, кажется, что это не проблема.

Вот основная часть класса db.

class DataBase(multiprocessing.Process):

    def __init__(self, conn_data, in_queue, out_queue):
        multiprocessing.Process.__init__(self)
        self.in_queue = in_queue
        self.out_queue = out_queue
        self.conn_data = conn_data
        self.all_ok = True

    def run(self):  
        proc_name = self.name
        self.conn = self.get_connection(self.conn_data)
        print("Running ", self.name)
        while True:
            next_job = self.in_queue.get()
            print("Next Job: ",next_job)
            if next_job is None:
                # Stop Process
                break
            SQL = next_job[0]
            callback = next_job[1]
            result = self.execute(SQL)
            self.out_queue.put((result, callback))
        print("Closing connection ", self.name)
        self.conn.close()
        return      

А в графическом интерфейсе у меня это так:

def recieve_data(self):
    "Revived data on the queue.  Data is a tuple of the actual data and a calback name."
    if self.recieve_queue.empty() == False:
        data = self.recieve_queue.get()
        callback_name = data[1]
        try:
            callback = getattr(self, callback_name)
            callback(data[0])
        except AttributeError as e:
            util.error_ui(err = e)
        self.check_data_timeout = None
        return False # Stop checking.
    return True  # Have the main loop keep checking for data.

def request_data(self, SQL, callback):
    self.send_queue.put((SQL, callback))
    self.check_data_timeout = gobject.timeout_add(50, self.recieve_data) # Poll the database recieved_queue

Ответы [ 3 ]

0 голосов
/ 18 ноября 2009

Вы пытались открыть новое соединение с базой данных для каждого из ваших процессов? Мне кажется, что вы просто добавляете накладные расходы, пытаясь использовать их в разных процессах.

Кроме того, я не уверен (ваш пример слишком мал для вывода), но похоже, что вы открываете новое соединение с БД для каждого запроса ... Вы закрываете соединение с self.conn.close() после каждого запроса? У вас должно быть одно длительное соединение.

0 голосов
/ 19 ноября 2009

Кажется, это проблемы или ошибка, специфичная для Ubuntu 9.10

Все отлично работает на Ubuntu 9.04 и win32, даже на win32 на виртуальной машине, размещенной на Ubuntu 9.10.

Спасибо за все советы.

0 голосов
/ 18 ноября 2009

Попробуйте выделить то, что занимает время - это многопроцессорная обработка или база данных? Например, попробуйте вызвать базу данных напрямую из интерактивной оболочки python - оболочка ipython имеет команды time и timeit для измерения подобных вещей. Или же заглушите DataBase.execute, чтобы вернуть постоянные значения, и посмотрите, какая разница.

А как насчет gobject.timeout_add? Что это делает? Вполне возможно, что здесь есть задержка, а не база данных или многопроцессорный код.

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