Настройки производительности запросов postgres - PullRequest
1 голос
/ 01 февраля 2010

У меня есть веб-приложение, которое выполняет поиск в представлении postgresql с 33.000 строками. Если я попробую это в одиночку, потребуется около 1-2 секунд, чтобы получить результат, и это нормально, я сначала подумал. Но затем я скачал инструмент стресс-тестирования веб-приложений от Microsoft, чтобы немного нагрузить на мое веб-приложение. Таким образом, я попробовал это сначала с 10 одновременными "пользователями". Когда тест запускается, и я выполняю поиск, это занимает гораздо больше времени, и мне нужно подождать около 10-20 секунд, чтобы получить мой результат, что я считаю недопустимым. Поскольку я новичок в «дыре» в базе данных (Postgresql), я много читаю за последние 3-4 дня, но не могу сделать поиск быстрее. Я изменил некоторые параметры конфигурации, такие как work_mem, shared_buffer и т. Д., Но это не улучшается.

Итак, мой вопрос: кто-нибудь может дать мне советы, что я могу изменить в моей конфигурации или на моем сервере, чтобы получить более высокую производительность, чем у десяти одновременно работающих пользователей?

Вот некоторые подробности о сервере и представлении:

Сервер (виртуальная машина):

3 GHZ Xeon
3 GB Ram
40 GB Harddrive

Оператор Select представления выглядит примерно так:

SELECT my selects, ....   
FROM tab1
JOIN tab2 ON tab1.index1 = tab2.index1
JOIN tab3 ON tab1.index0 = tab3.index0
JOIN tab4 ON tab1.index1 = tab4.index1;

Я установил индекс для каждого индекса1 и индекса0.

Объяснить анализ (по умолчанию postgres.conf):

EXPLAIN ANALYZE SELECT * from view_myview;

Nested Loop  (cost=0.90..29042.71 rows=49840 width=1803) (actual time=0.384..5380.477 rows=33620 loops=1)  
 ->  Merge Join  (cost=0.90..11740.81 rows=24403 width=1257) (actual time=0.263..2548.377 rows=22601 loops=1)
     Merge Cond: (tab2.index1 = tab1.index1)
     ->  Merge Join  (cost=0.00..7170.63 rows=15968 width=1251) (actual time=0.157..1225.752 rows=15968 loops=1)
           Merge Cond: (tab2.index1 = tab4.index1)
           ->  Index Scan using tab2_index1_idx on tab2 (cost=0.00..3617.45 rows=15968 width=1025) (actual time=0.053..239.399 rows=15968 loops=1)
           ->  Index Scan using tab4_index1_idx on tab4 (cost=0.00..3310.83 rows=17103 width=226) (actual time=0.045..253.721 rows=17103 loops=1)
     ->  Index Scan using tab1_index1_0_idx on tab4  (cost=0.00..4226.13 rows=24403 width=50) (actual time=0.051..347.333 rows=24403 loops=1)
->  Index Scan using tab3_index0_idx on tab3 (cost=0.00..0.64 rows=2 width=568) (actual time=0.030..0.050 rows=1 loops=22601)
     Index Cond: (tab3.index0 = tab1.index0)
Total runtime: 5814.165 ms

Надеюсь, что кто-нибудь может помочь,

Nico

Ответы [ 3 ]

1 голос
/ 01 февраля 2010

Вы на самом деле читаете весь вид каждый раз, без какой-либо фильтрации? Если это означает, что вы выполняете фильтрацию в приложении, вам действительно следует опустить их как предложения WHERE. Если вы делаете это с предложениями WHERE и просто не включаете это в пост здесь, то вам нужно сделать репост с включенным: -)

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

План выглядит немного странно - какие именно параметры конфигурации вы изменили и на какие?

0 голосов
/ 03 февраля 2010

Как вы сказали, отдельный запрос, который вы показываете в своем вопросе, не является реальной проблемой.

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

Объясните, что анализ вашей публикации бесполезен - покажите реальный запрос с условием WHERE. Время (в выводе объяснения анализа) доказывает только то, что ваш сервер просто перегружен в данный момент. 5 секунд времени для запроса на 40 тыс. Строк? - это действительно трагично.

Вам необходимо обнаружить запросы, которые потребляют большую часть ресурсов сервера. Чтобы добиться этого, выполните статистику рабочей нагрузки с помощью такого инструмента, как pgfouine . это займет некоторое время, но оно того стоит.

Я бы также посмотрел статистику вашей системы (использование ввода-вывода, память, процессор), прежде чем угадывать.

Если это будет производственный сервер, настройте инструмент мониторинга - если у вас его еще нет. Я бы порекомендовал munin , довольно легко настроить и запустить за 15 минут (поставляется в комплекте с некоторыми дистрибутивами Linux).

0 голосов
/ 01 февраля 2010

Это звездный запрос, но по какой-то причине PostgreSQL решает использовать MERGE JOIN между таблицами измерений.

Результаты сканирования целых индексов tab1, tab2 и tab4, которые загромождают кэш.

Попробуйте увеличить shared_buffer, чтобы все три индекса подходили туда.

Кроме того, не могли бы вы опубликовать результаты следующих запросов?

SELECT  COUNT(*)
FROM    tab2
JOIN    tab4
ON      tab2.index1 = tab4.index1

SELECT  COUNT(*)
FROM    tab2
JOIN    tab4
ON      tab2.index1 = tab4.index1
JOIN    tab1
ON      tab1.index1 = tab4.index1

SELECT  COUNT(*)
FROM    tab1
JOIN    tab3
ON      tab3.index0 = tab1.index0

SELECT  COUNT(*)
FROM    tab1
JOIN    tab4
ON      tab1.index1 = tab4.index1

SELECT  COUNT(*)
FROM    tab1
JOIN    tab2
ON      tab1.index1 = tab2.index1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...