Postgresql: запрос в 10 раз медленнее в другом клиенте
Глядя на журнал сервера postgres, я вижу, что точно такой же запрос на том же сервере postgres занимает гораздо больше времени (примерно в 10 раз больше) при вызове из клиента Linux или из клиента Windows.
Запросы поступают из приложения Django, работающего на машине Linux с 4 ГБ оперативной памяти и на машине Windows с 8 ГБ оперативной памяти. Обе среды pyhon имеют библиотеку psycopg2 версии 2.4.4 для отправки запросов на один и тот же сервер postgres.Ниже расположен сервер postgres журналы
Запрос windows (со временем):
2013-06-11 12:12:19 EEST [unknown] 10.1.3.152(56895) mferreiraLOG: duration: 3207.195 ms statement: SELECT "autotests_tracerperformance"."id", "autotests_tracerperformance"."date", "autotests_tracerperformance"."video_id", "autotests_tracerperformance"."revision_id", "autotests_tracerperformance"."computer_id", "autotests_tracerperformance"."probe", "autotests_tracerperformance"."time_tostart", "autotests_tracerperformance"."hang_atstart", "autotests_tracerperformance"."time_tohang", "autotests_tracerperformance"."hang", "autotests_tracerperformance"."crash", "autotests_tracerperformance"."stacktrace", "autotests_tracerperformance"."framemax", "autotests_tracerperformance"."maxtime", "autotests_tracerperformance"."avgtime" FROM "autotests_tracerperformance" INNER JOIN "revisions" ON ("autotests_tracerperformance"."revision_id" = "revisions"."id") WHERE ("autotests_tracerperformance"."computer_id" = 61 AND "revisions"."repo" = 'Trunk' )
Запрос linux (намного длиннее):
2013-06-11 12:12:56 EEST [unknown] 10.1.3.154(35325) mferreiraLOG: duration: 22191.773 ms statement: SELECT "autotests_tracerperformance"."id", "autotests_tracerperformance"."date", "autotests_tracerperformance"."video_id", "autotests_tracerperformance"."revision_id", "autotests_tracerperformance"."computer_id", "autotests_tracerperformance"."probe", "autotests_tracerperformance"."time_tostart", "autotests_tracerperformance"."hang_atstart", "autotests_tracerperformance"."time_tohang", "autotests_tracerperformance"."hang", "autotests_tracerperformance"."crash", "autotests_tracerperformance"."stacktrace", "autotests_tracerperformance"."framemax", "autotests_tracerperformance"."maxtime", "autotests_tracerperformance"."avgtime" FROM "autotests_tracerperformance" INNER JOIN "revisions" ON ("autotests_tracerperformance"."revision_id" = "revisions"."id") WHERE ("autotests_tracerperformance"."computer_id" = 61 AND "revisions"."repo" = 'Trunk' )
Выполнение прямо из psql (самый быстрый):
2013-06-11 12:19:06 EEST psql [local] mferreiraLOG: duration: 1332.902 ms statement: SELECT "autotests_tracerperformance"."id", "autotests_tracerperformance"."date", "autotests_tracerperformance"."video_id", "autotests_tracerperformance"."revision_id", "autotests_tracerperformance"."computer_id", "autotests_tracerperformance"."probe", "autotests_tracerperformance"."time_tostart", "autotests_tracerperformance"."hang_atstart", "autotests_tracerperformance"."time_tohang", "autotests_tracerperformance"."hang", "autotests_tracerperformance"."crash", "autotests_tracerperformance"."stacktrace", "autotests_tracerperformance"."framemax", "autotests_tracerperformance"."maxtime", "autotests_tracerperformance"."avgtime" FROM "autotests_tracerperformance" INNER JOIN "revisions" ON ("autotests_tracerperformance"."revision_id" = "revisions"."id") WHERE ("autotests_tracerperformance"."computer_id" = 61 AND "revisions"."repo" = 'Trunk' );
Другие запросы, которым не нужно загружать так много элементов из базы данных, выполняют почти то же самое.
Почему так велики временные различия между клиентами для этого запроса?
Примечание : время передачи не имеет значения, так как все машины находятся в одной интрасети. Кроме того, более медленные времена видны, когда клиентский запрос поступает с той же машины Linux, на которой запущен сервер postgresql.
Примечание 2 : Psycopg2 был установлен по-разному в Windows и Linux. В то время как в Windows я установил его из предварительно упакованного двоичного файла, в Linux я запустил "pip install psycopg2", который опирается на установку postgresql, доступную в системе. Может ли это привести к различным значениям параметров, влияющих на производительность на стороне клиента (например, параметр 'work_mem')?
1 ответ:
Вы можете проверить, выполняет ли медленный клиент шифрование SSL или нет. Это происходит по умолчанию, когда он настроен на сервере и клиент был скомпилирован с поддержкой SSL.
Для запросов, извлекающих большие объемы данных, разница во времени существенна. Кроме того, некоторые дистрибутивы Linux, такие как Debian/Ubuntu, имеют SSL по умолчанию, даже для TCP-соединений через localhost.
В качестве примера приведем разницу во времени для запроса, извлекающего 1,5 м строк весом a всего 64 Мбайт, с теплым кэшем.
Без шифрования:
$ psql "host=localhost dbname=mlists sslmode=disable" Password: psql (9.1.7, server 9.1.9) Type "help" for help. mlists=> \timing Timing is on. mlists=> \o /dev/null mlists=> select subject from mail; Time: 1672.258 msС шифрованием:
$ psql "host=localhost dbname=mlists" Password: psql (9.1.7, server 9.1.9) SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256) Type "help" for help. mlists=> \o /dev/null mlists=> \timing Timing is on. mlists=> select subject from mail; Time: 7017.935 msЧтобы отключить его глобально, можно установить
SSL=off
вpostgresql.conf
.Чтобы отключить его для определенных диапазонов адресов клиентов, добавьте записи в
pg_hba.conf
сhostnossl
в первом поле перед более общими записямиhost
.Чтобы отключить if на стороне клиента, это зависит от того, как драйвер предоставляет параметр соединения
sslmode
. Если это не так, то переменная окруженияPGSSLMODE
может использоваться, если драйвер реализован поверхlibpq
.Что касается соединений через доменные сокеты Unix (
local
), SSL никогда не используется с ними.