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 7

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 никогда не используется с ними.