Как Вы делаете Python / PostgreSQL быстрее?

Statement myStmt = myConn.createStatement();
ResultSet resultSet = myStmt.executeQuery("SELECT * FROM `Employee`");
boolean check = false;
while(resultSet.next()){ 
    if(resultSet.getString("username").matches(textField_1.getText()) && resultSet.getString("password").matches(textField_2.getText())){ 
        System.out.println("Matched!");
        check = true;
        break;
    }

}
if (check == false){

      System.out.println("Invalid username or password!");
}

Теперь цикл while будет искать правильное имя пользователя и пароль, если не будет печатать Invalid.

6
задан Sam Harwell 3 November 2009 в 04:01
поделиться

5 ответов

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

Три вещи.

Один. Не ВЫБИРАЙТЕ много раз для приспосабливания Дате, Имени хоста и размерам Человека. Выберите все данные ОДНАЖДЫ в словарь Python и используйте их в памяти. Не делайте повторенный одиночный элемент выбирает. Используйте Python.

Два. Не обновлять.

А именно, не делайте этого. Это - плохой код по двум причинам.

cursor.execute("UPDATE people SET chats_count = chats_count + 1 WHERE id = '%s'" % person_id)

Это быть замененным простым ИЗБРАННЫМ КОЛИЧЕСТВОМ (*) ОТ.... Никогда не обновляйте для постепенного увеличения количества. Просто считайте строки, которые являются там с оператором SELECT. [Если Вы не можете сделать этого с простым ИЗБРАННЫМ КОЛИЧЕСТВОМ или ВЫБРАТЬ (ОТЛИЧНОЕ) КОЛИЧЕСТВО, Вы пропускаете некоторые данные - Ваша модель данных должна всегда обеспечивать корректные полные количества. Никогда не обновляйте.]

И. Никогда не создавайте SQL с помощью строковой замены. Абсолютно немой.

Если, по некоторым причинам SELECT COUNT(*) не достаточно быстро (сравните сначала, прежде, чем сделать что-либо Ламе), можно кэшировать результат количества в другой таблице. ПОСЛЕ всех загрузок. Сделайте a SELECT COUNT(*) FROM whatever GROUP BY whatever и вставьте это в таблицу количеств. Не Обновлять. Когда-либо.

Три. Использование связывает переменные. Всегда.

cursor.execute( "INSERT INTO ... VALUES( %(x)s, %(y)s, %(z)s )", {'x':person_id, 'y':time_to_string(time), 'z':channel,} )

SQL никогда не изменяется. Значения, связанные в изменении, но SQL никогда, не изменяются. Это НАМНОГО быстрее. Никогда не создавайте SQL-операторы динамично. Никогда.

8
ответ дан 8 December 2019 в 13:51
поделиться

Использование связывает переменные вместо литеральных значений в sql операторах и создает курсор для каждого уникального sql оператора так, чтобы оператор не должен был быть повторно проанализирован в следующий раз, когда это используется. Из документа API дб Python:

Подготовьте и выполните операцию базы данных (запрос или команда). Параметры могут быть обеспечены как последовательность или отображение и будут связаны с переменными в операции. Переменные указаны в определенной для базы данных нотации (см. атрибут paramstyle модуля для деталей). [5]

Ссылка на операцию будет сохранена курсором. Если тот же объект операции передается в снова, то курсор может оптимизировать свое поведение. Это является самым эффективным для алгоритмов, где та же операция используется, но различные параметры связываются с нею (много раз).

ВСЕГДА ВСЕГДА ВСЕГДА использование связывает переменные.

3
ответ дан 8 December 2019 в 13:51
поделиться

В для цикла, Вы вставляете в таблицу 'чатов' неоднократно, таким образом, Вам только нужен единственный sql оператор с, связывают переменные, чтобы быть выполненным с различными значениями. Таким образом, Вы могли поместить это перед для цикла:

insert_statement="""
    INSERT INTO chats(person_id, message_type, created_at, channel)
    VALUES(:person_id,:message_type,:created_at,:channel)
"""

Затем вместо каждого sql оператора Вы выполняетесь, помещает это на месте:

cursor.execute(insert_statement, person_id='person',message_type='msg',created_at=some_date, channel=3)

Это сделает вещи выполненными быстрее потому что:

  1. Объект курсора не должен будет повторно анализировать оператор каждый раз
  2. Сервер дб не должен будет генерировать новый план выполнения, поскольку он может использовать тот, который он создает ранее.
  3. Вы не должны будете называть santitize (), поскольку специальные символы в связывать переменных не отделятся sql оператора, который выполняется.

Примечание: Связывать переменным синтаксисом, который я использовал, является конкретная Oracle. Необходимо будет проверить документацию psycopg2 библиотеки на точный синтаксис.

Другая оптимизация:

  1. Вы увеличиваете с "chatscount НАБОРА людей ОБНОВЛЕНИЯ" после каждого повторения цикла. Сохраните словарь, отображающий пользователя на chat_count, и затем выполните оператор общего количества, которое Вы видели. Это будет быстрее затем поражать дб после каждой записи.
  2. Использование связывает переменные на ВСЕХ Ваших запросах. Не только оператор вставки, я выбираю это в качестве примера.
  3. Измените весь find_ * () функции, которые делают взлеты взгляда дб для кэширования их результатов, таким образом, они не должны поражать дб каждый раз.
  4. психо оптимизирует программы Python, которые выполняют большое количество numberic операции. Сценарий IO дорогой и не ЦП, дорогой, таким образом, я не ожидал бы давать Вам очень если любая оптимизация.
3
ответ дан 8 December 2019 в 13:51
поделиться

Как предложенный Mark, используйте обязательные переменные. База данных только должна подготовить каждый оператор однажды, затем "восполнить пробелы" для каждого выполнения. Как хороший побочный эффект, это будет автоматически заботиться о заключающих в кавычки строку проблемах (который Ваша программа не обрабатывает).

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

Ваши log_hostname, log_person, и функции log_date делают бесполезные ВЫБОРЫ на таблицах. Сделайте атрибуты соответствующей таблицы PRIMARY KEY или УНИКАЛЬНЫЙ. Затем вместо того, чтобы проверить на присутствие ключ ПЕРЕД ВСТАВКОЙ, просто сделайте ВСТАВКУ. Если человек/дата/имя хоста уже будет существовать, то ВСТАВКА перестанет работать от ограничительного нарушения. (Это не будет работать при использовании транзакции с единственной фиксацией, как предложено выше.)

С другой стороны, если Вы знаете, что Вы - единственная ВСТАВКА в таблицы, в то время как Ваша программа работает, затем создайте параллельные структуры данных в памяти и поддержите их в памяти, в то время как Вы делаете свои ВСТАВКИ. Например, читайте во всех именах хостов из таблицы в ассоциативный массив в начале программы. Когда хотят знать, сделать ли ВСТАВКУ, просто сделать поиск массива. Если никакая найденная запись, не сделайте ВСТАВКУ и обновите массив соответственно. (Это предложение совместимо с транзакциями и единственной фиксацией, но требует большего количества программирования. Это будет злобно быстрее, все же.)

2
ответ дан 8 December 2019 в 13:51
поделиться

Дополнительно ко многим прекрасным предложениям @Mark Roddy дал, сделайте следующее:

  • не использовать readlines, можно выполнить итерации по объектам файла
  • попытайтесь использовать executemany вместо execute: попытайтесь сделать, пакет вставляет довольно единственные вставки, это имеет тенденцию быть быстрее, потому что существует меньше служебное. Это также сокращает количество фиксаций
  • str.rstrip будет работать просто великолепно вместо того, чтобы лишить новой строки с regex

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

1
ответ дан 8 December 2019 в 13:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: