2010-02-01 3 views
1

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

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

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

Сервер (Virual машина):

3 GHZ Xeon 
3 GB Ram 
40 GB Harddrive 

Выбрать утверждение зрения выглядит примерно так:

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 и index0.

Explain, Analyze (с по умолчанию 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 

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

Нико

ответ

0

Это звезда запрос, но по какой-то причине 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 
+0

Как я отмечаю выше, этот запрос не является пробойной пробой. Моя проблема в том, что очень много времени, когда я запрашиваю у многих людей в базе данных. Я понятия не имею, как работает БД, но я думал, что postgres открывает 10 процессов и обрабатывает запросы процесса my View. Поэтому мне не нужно ждать завершения каждого процесса. Я сказал вам результаты завтра. У меня не хватает времени:/ – Nico

1

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

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

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

+0

Я фильтрую. Если я делаю это, не занимайте столько времени, но моя проблема не в том, что один запрос. Моя проблема в том, что очень много времени, когда я запрашиваю у многих людей в базе данных. Я понятия не имею, как работает БД, но я думал, что postgres открывает 10 процессов и обрабатывает запросы процесса my View. Поэтому мне не нужно ждать завершения каждого процесса. Если вы понимаете, о чем я? – Nico

0

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

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

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

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

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

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

Смежные вопросы