LINUX.ORG.RU

PostgreSQL v7.3.3 is out


0

0

Вышла новая версия PostgreSQL в ветке v7.3 - v7.3.3, изменения представляют собой множество фиксов важных и неочень, в том числе и из v7.4 ветки.

Разработчики рекомендуют обновиться всем тем кто использует более раниие версии PostgreSQL v7.3.x

>>> Анонс

★★★★★

green (*) (2003-05-31 19:49:09.484034):

> postgresql.conf конечно правили, но что там нужно поменять чтоб именно такие запросы рулили? ;)

чему равны параметры sort_mem и shared_buffers?

> vacuum analyze раз в сутки. id конечно же integer

хорошо. всё же переспрошу: именно int4, а не int2/int8?

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

ну, надеюсь по всем полям, по которым JOIN идёт, индексы построены. при взгляде на запрос (результат EXPLAIN-то я не видел) кажется, что тут бы мог помочь такой индекс:

CREATE INDEX del_info_moderation_idx ON del_info (msgid, delby)

либо можно ещё попробовать переписать запрос в таком виде:

SELECT sections.name as ptitle, groups.title as gtitle, topics.title, topics.id as msgid, del_info.reason, comments.postdate FROM sections, groups, topics, ( SELECT comments.topic, del_info.reason, comments.postdate, comments.id FROM comments, del_info WHERE del_info.msgid = comments.id AND comments.userid = 639 AND del_info.delby != comments.userid ) AS del_comments WHERE sections.id = groups.section AND groups.id = topics.groupid AND del_comments.topic = topics.id ORDER BY del_comments.id DESC LIMIT 20;

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

anonymous
()
Ответ на: комментарий от anonymous

Зачем мейл? Прямо тут и пиши инструкции. Или это секретное знание доступное только избранным?

green ★★★★★
() автор топика
Ответ на: комментарий от anonymous

На тех кратеньких тестах которые я тут провожу (http://lor-test.linuxhacker.ru/view-section.jsp?section=2 бегает поверх mysql) видно что пока что никакой особой оптимизации там ненадо :) Другое дело что нужно сидеть ковырять код, переписывать запросы, избавляться от триггеров и заменять их на логику в коде... Когда с этим будет покончено (если будет), можно будет задуматься о чем-то еще, если все еще останется необходимость.

green ★★★★★
() автор топика


Еще хотелось бы знать параметры железа, Процессор/частота/тип и объем памяти/тип и модель hdd.

anonymous
()
Ответ на: комментарий от green


> видно что пока что никакой особой оптимизации там ненадо :)

А, так значит уже нравится? ;) Толи еще будет, если грамотно оптимизировать...

anonymous
()


Я все-таки рекомендую mysql-4,0.x, так как в нем можно включить кеширование запросов, что может дать более чем двухкратный прирост производительности на запросах к редкоизменяемым таблицам.

anonymous
()
Ответ на: комментарий от anonymous

sort_mem = 4096
shared_buffers = 310

id - типа integer, там не написано какой именно, так что я подозреваю что 4х байтный

По поводу select - я воспользовался похожим способом, только сначала я делаю несортированный select во временную таблицу, а оттуда забираю уже с сортировкой ;)

Query plan:
Limit (cost=0.00..33368.59 rows=7 width=129)
-> Nested Loop (cost=0.00..37346.83 rows=8 width=129)
-> Nested Loop (cost=0.00..37316.47 rows=8 width=114)
-> Nested Loop (cost=0.00..37279.79 rows=8 width=90)
-> Nested Loop (cost=0.00..37250.03 rows=8 width=49)
Join Filter: ("outer".delby <> "inner".userid)
-> Index Scan Backward using del_info_pkey on del_info (cost=0.00..270.40 rows=12088 width=29)
-> Index Scan using comments_pkey on comments (cost=0.00..3.04 rows=1 width=20)
Index Cond: ("outer".msgid = comments.id)
Filter: (userid = 639)
-> Index Scan using topics_pkey on topics (cost=0.00..3.79 rows=1 width=41)
Index Cond: ("outer".topic = topics.id)
-> Index Scan using groups_pkey on groups (cost=0.00..4.67 rows=1 width=24)
Index Cond: (groups.id = "outer".groupid)
-> Index Scan using sections_pkey on sections (cost=0.00..3.86 rows=1 width=15)
Index Cond: (sections.id = "outer".section)
(16 rows)

Кстати приведенный "оптимизированный" запрос возвращает другой ответ чем "неоптимизированный" и выполняется не меньше (а то и больше).

green ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Нравится-не нравится, но переписывать логику с триггеров на непойми что - тоже тот еще прикол. Так что я бы предпочел чтобы мне показали как правильно настроить postgres ;)

green ★★★★★
() автор топика
Ответ на: комментарий от anonymous

На текущий момент железо - P3-650, 512M RAM/SDRAM-PC100 (но на деле учитывая жабу, и вссякие другие - доступно поменьше ;) ) винт обычный Quantum fireball в udma4 mode. То есть ничего сверхестественного само собой ;)

green ★★★★★
() автор топика
Ответ на: комментарий от green


> Так что я бы предпочел чтобы мне показали как правильно настроить postgres ;)

Ну и соси тогда лохматого, двоечник. Я два раза не предлагаю.
Горбатых исправляет тольго могила.

anonymous
()

green (*) (2003-05-31 20:19:38.078684):

> shared_buffers = 310

это 2,5 мегабайта (310*8кб) на кэш. Надо бы побольше, Гуру (Bruce Momjian) рекомендует четверть памяти, я с ним более-менее согласен.

> Query plan:

*очень* подозрительный Query plan. Никто не игрался с параметрами типа enable_seqscan? Должен быть on, иначе часть запросов (где выгодней seq_scan) будет на ровном месте тормозить. проверь!

да, а индекс по comments.userid есть???

> Кстати приведенный "оптимизированный" запрос возвращает другой ответ чем "неоптимизированный" и выполняется не меньше (а то и больше).

ну, проверить-то мне его не на чем было, наугад писал. :)

sad_spirit
()
Ответ на: комментарий от sad_spirit

по поводу shared_buffers - написано буквально следующее - "# 2*max_connections, min 16, typically 8KB each" таким образом нигде не написано что это как-то влияет на производительность. Где он такое рекомендует? url?

seqscan действительно запрещен.Но помнится никакого влияния оно не оказывало когда я с этим экспериментировал.

индекс по userid есть.

green ★★★★★
() автор топика
Ответ на: комментарий от green


> Или это секретное знание доступное только избранным?

Ну а хрена ли ты думал? Пришел зеленый green, поставил rpm, и
все заработало так, как у дедушки, который десять лет на этом
бабки зарабатывает?

anonymous
()

green (*) (2003-05-31 20:42:14.430117):

> по поводу shared_buffers - написано буквально следующее - "# 2*max_connections, min 16, typically 8KB each" таким образом нигде не написано что это как-то влияет на производительность. Где он такое рекомендует? url?

http://www.ca.postgresql.org/docs/momjian/hw_performance/

'shared buffers' это грубо говоря дисковый кэш, через который postgres читает данные. сделай хотя бы метра 64, если всего памяти 512. хотя без выполнения следующего пункта может и не помочь...

> seqscan действительно запрещен.Но помнится никакого влияния оно не оказывало когда я с этим экспериментировал.

включи!!! его имеет смысл отключать только для хорошо проверенных *отдельных* запросов. а так после 'настройки' postgres тормозит только больше.

вот попробуй прямо щас:

set enable_seqscan = on; explain analyze твой запрос;

sad_spirit
()
Ответ на: комментарий от anonymous

Вообще-то прежде чем "поставил rpm", есть еще два шага - "вытянул src.rpm" и "собрал бинарный rpm из src.rpm" ;)

green ★★★★★
() автор топика
Ответ на: комментарий от sad_spirit

Да, я уже вижу что он был отключен совершенно зря. Спасибо.

green ★★★★★
() автор топика
Ответ на: комментарий от sad_spirit

Да, очень любопытная ссылка. Интересно, а что такое тогда "effective_cache_size"?

green ★★★★★
() автор топика

> Да, я уже вижу что он был отключен совершенно зря. Спасибо.

Пожалста. :]

Кинь сюда ради интереса EXPLAIN ANALYZE при включённом seq_scan.

> Да, очень любопытная ссылка. Интересно, а что такое тогда "effective_cache_size"?

http://www.postgresql.org/docs/view.php?version=7.3&idoc=1&file=runti...

sad_spirit
()
Ответ на: комментарий от sad_spirit

 Limit  (cost=872.99..873.01 rows=7 width=129) (actual time=147.16..147.19 rows=
12 loops=1)
   ->  Sort  (cost=872.99..873.01 rows=8 width=129) (actual time=147.15..147.16 
rows=12 loops=1)
         Sort Key: del_info.msgid
         ->  Hash Join  (cost=870.72..872.87 rows=8 width=129) (actual time=144.
48..146.37 rows=12 loops=1)
               Hash Cond: ("outer".section = "inner".id)
               ->  Hash Join  (cost=869.66..871.65 rows=8 width=114) (actual tim
e=144.27..145.99 rows=12 loops=1)
                     Hash Cond: ("outer".id = "inner".groupid)
                     ->  Seq Scan on groups  (cost=0.00..1.45 rows=45 width=24) 
(actual time=0.17..1.46 rows=45 loops=1)
                     ->  Hash  (cost=869.64..869.64 rows=8 width=90) (actual tim
e=143.92..143.92 rows=0 loops=1)
                           ->  Nested Loop  (cost=564.44..869.64 rows=8 width=90
) (actual time=91.28..143.83 rows=12 loops=1)
                                 ->  Hash Join  (cost=564.44..839.87 rows=8 width=49) (actual time=80.39..131.74 rows=12 loops=1)
                                       Hash Cond: ("outer".msgid = "inner".id)
                                       Join Filter: ("outer".delby <> "inner".userid)   
                                       ->  Seq Scan on del_info  (cost=0.00..214.88 rows=12088 width=29) (actual time=0.18..56.61 rows=12092 loops=1)
                                       ->  Hash  (cost=564.02..564.02 rows=167 width=20) (actual time=46.42..46.42 rows=0 loops=1)
                                             ->  Index Scan using comment_author on comments  (cost=0.00..564.02 rows=167 width=20) (actual time=0.76..42.94 rows=996 loops=1)
                                                   Index Cond: (userid = 639)
                                 ->  Index Scan using topics_pkey on topics  (cost=0.00..3.79 rows=1 width=41) (actual time=0.98..0.98 rows=1 loops=12)
                                       Index Cond: ("outer".topic = topics.id)
               ->  Hash  (cost=1.05..1.05 rows=5 width=15) (actual time=0.06..0.06 rows=0 loops=1)
                     ->  Seq Scan on sections  (cost=0.00..1.05 rows=5 width=15) (actual time=0.03..0.05 rows=5 loops=1)
 Total runtime: 148.55 msec
(22 rows)

green ★★★★★
() автор топика

Всего один Nested loop - вместо нескольких выше, это очень хорошо, если обратить внимание именно Nested loop "съедает" производительность.
green: есть еще оптимизация самого PostgreSQL под железо (gcc3 обязательно и -march=pentium3 -msse -msse2 -mfpmath=sse) но это надо хорошо протестировать перед использованием, потому что еще довольно таки ново, хотя раньше я использовал на gcc2 пересборку под -march=pentiumpro и работало быстрее. Еще можно проверить скорость винта и затюнить его под размеры блоков PostgreSQL - см. hdparm -tT /dev/hdx и hdparm -m16 -a16 /dev/hdx. Отключение поддержки UNICODE при сборке PostgreSQL дает до 30% скорости работы с символьными полями, да и с их выборкой, если UNICODE не используется, лучше пересобрать без него, и заодно отключить locale и recode - но делать это только в том случае, если в/из базы пишут/читают в одной кодировке.

2green: попробуй сборку с оптимизацией и hdparm потюнить, и если можешь - пришли сюда ваши postgresql.conf, rc.pgres (?) и ps -axf|grep postgres. Хотелось бы оценить параметры, которые вы еще там изменили или стоят по умолчанию :)

saper ★★★★★
()
Ответ на: комментарий от saper

Сборка с оптимизацией есть since day one ввиду сильной заметности эффекта с первой попытки ;).
Винт трогать смысла особого я не вижу сейчас. UNICODE используется местами, так что отключать его нельзя.

postgresql.conf:
max_connections = 102
shared_buffers = 7000
max_locks_per_transaction = 64
wal_buffers = 20
sort_mem = 4096
vacuum_mem = 81920
checkpoint_segments = 3
checkpoint_timeout = 300
commit_delay = 100
fsync = false
wal_sync_method = fdatasync
enable_seqscan = true
enable_indexscan = true
enable_tidscan = true
enable_sort = true
enable_nestloop = true
enable_mergejoin = true
enable_hashjoin = true
effective_cache_size = 10000
geqo = true
explain_pretty_print = true
stats_start_collector = true
stats_row_level = true
stats_block_level = true
max_files_per_process = 1150

[green@shrek somedir]$ ps axf | grep postgres
24607 pts/9 S 0:00 \_ postgres: stats buffer process
24608 pts/9 S 0:00 | \_ postgres: stats collector process
24688 pts/9 S 0:00 \_ postgres: linuxorgrubase lordbuser 127.0.0.1 idle
24691 pts/9 S 0:00 \_ postgres: linuxorgrubase lordbuser 127.0.0.1 idle
24692 pts/9 S 0:00 \_ postgres: linuxorgrubase lordbuser 127.0.0.1 idle
24693 pts/9 S 0:00 \_ postgres: linuxorgrubase lordbuser 127.0.0.1 idle
24694 pts/9 S 0:00 \_ postgres: linuxorgrubase lordbuser 127.0.0.1 idle
24695 pts/9 S 0:00 \_ postgres: linuxorgrubase lordbuser 127.0.0.1 idle
24696 pts/9 S 0:26 \_ postgres: linuxorgrubase lordbuser 127.0.0.1 idle
24697 pts/9 S 0:00 \_ postgres: linuxorgrubase lordbuser 127.0.0.1 idle
24698 pts/9 S 1:13 \_ postgres: linuxorgrubase lordbuser 127.0.0.1 idle
24699 pts/9 S 0:00 \_ postgres: linuxorgrubase lordbuser 127.0.0.1 idle
27013 pts/9 S 0:00 \_ postgres: linuxorgrubase lordbuser 127.0.0.1 idle
27014 pts/9 S 0:05 \_ postgres: linuxorgrubase lordbuser 127.0.0.1 idle
29051 pts/9 S 0:00 \_ postgres: otherbase otheruser 127.0.0.1 idle

green ★★★★★
() автор топика

COMMENTS:
Настройки хорошие :) Разве что 7000 не было бы много, мы для 512Mb сервера с 40 соединениями ставили 4096, так что если память пойдет вниз - и своп зашумит, попробуй 4096.
fsync = false :))) видимо редко питание у него отключают, но это хорошее значение!
geqo = true по идее он вообще не должен использоваться, но мы, сколько не бились при супер-тяжелых запросах и включении этого GEQO только теряли по скорости их выполнения, поэтому у нас geqo = false. Возможно он вообще не вызывается у вас...
И еще - надеюсь при пуске самого PostgreSQL все DEBUG-и отключены, во всяком случае те, что пишут не о соединениях пользователей, а все запросы которые они отсылают, от этого PostgreSQL очень тормозит при реальной загрузке, для отладки - Ок.
QUESTIONS:
А вот чему равно значение в /proc/sys/kernel/shmmax?
И если совсем не влом, все же интересно hdparm /dev/hdx и hdparm -tT /dev/hdx.
И еще - почему локльные клиенты соединяются по TCP/IP через 127.0.0.1, а не через UNIX-сокеты?????

saper ★★★★★
()
Ответ на: комментарий от saper

Debug'и отключены.
$ cat /proc/sys/kernel/shmmax
134217728 (если б нехватало - оно бы не стартовало ;) )

# hdparm -tT /dev/hda

/dev/hda:
Timing buffer-cache reads: 128 MB in 2.09 seconds = 61.24 MB/sec
Timing buffered disk reads: 64 MB in 5.56 seconds = 11.51 MB/sec
Низкие цифры потому что я не могу все остановить ради измерения ;)
# hdparm /dev/hda

/dev/hda:
multcount = 0 (off)
IO_support = 3 (32-bit w/sync)
unmaskirq = 1 (on)
using_dma = 1 (on)
keepsettings = 0 (off)
readonly = 0 (off)
readahead = 8 (on)

(multcount не включен специально. Никакого смысла я в нем не вижу.)

green ★★★★★
() автор топика
Ответ на: комментарий от saper

А, да, клиенты через tcp/ip потому что jdbc по другому не умеет вроде бы.

green ★★★★★
() автор топика

2green: sort_mem = 4096
Не маловато будет? Ведь в запросах интенсивно исп. сортировка.
Для 512Mb это значение можно увеличить в два раза. Попробуй, плс.

Приведи еще команду для старта БД. Что-то вроде:
su -l postgres -c "/usr/local/pgsql/bin/pg_ctl -o '-i -B 48000' -D /home/postgres/data -p /usr/local/pgsql/bin/postmaster -l /home/postgres/logs/db.log start"

Korwin ★★★
()
Ответ на: комментарий от Korwin

Ну как-нить потом увеличу. На самом деле не вся память из имеющихся в наличии 512M доступна, как я уже говорил.
Стартуется стандартно: /usr/bin/pg_ctl -D $PGDATA -p /usr/bin/postmaster -o '-p ${PGPORT}' start

green ★★★★★
() автор топика

Ключ -B для postmaster:
-B nbuffers
Sets the number of shared buffers for use by the
server processes. This value defaults to 64
buffers, where each buffer is 8 kB.

Вмести с размером сортировки увеличивай, только если давать слишком большие значения PostgreSQL может вообще не запускаться по причине невозможности "захвата" такого объема память.

При тюнинге FreeBSD эти два параметра дали заметный выигрыш.

Korwin ★★★
()
Ответ на: комментарий от Korwin

Насколько я ничего не понимаю, -B это то же самое что и max_connections postgres.conf, так что по два раза его задавать никчему.

green ★★★★★
() автор топика

green (*) (2003-05-31 23:21:38.51444):

> Насколько я ничего не понимаю, -B это то же самое что и max_connections postgres.conf, так что по два раза его задавать никчему.

На самом деле, это то же самое, что shared_buffers там. :)

Настройки хорошие, теперь если будет тормозить, то надо уже конкретные таблицы/индексы/запросы оптимизировать.

для того есть statistics collector: http://www.postgresql.org/docs/view.php?version=7.3&idoc=1&file=monit... (слушаться saper'а и отключать его не советую).

Смотришь в pg_stat_user_tables из каких таблиц больше всего читается, и где делается больше всего seq_scan и строишь индексы, смотришь по pg_stat_user_indexes, какие индексы в жизни не используются и сносишь их (если, конечно, это не primary key/unique). В самые напряжённые моменты заглядываешь в pg_stat_activity и смотришь, какие запросы больше всего нагружают базу.

sad_spirit
()
Ответ на: комментарий от green


man говорит:
When this feature is enabled, it typically reduces operating system overhead for disk I/O by 30-50%. On many systems, it also provides increased data throughput of anywhere from 5% to 50%.

а green говорит: multcount не включен специально. Никакого смысла я в нем не вижу.

green ездил, green знает ;)

Я вообще не перестаю удивляться мудрости и прозорливости отцов
этого сайта ;)

anonymous
()
Ответ на: комментарий от sad_spirit

Угу, не то запастил ;) Спасибо за помощь.

green ★★★★★
() автор топика

-B это shared_buffers, а не max_connections :)
sad_spirit: надо уже конкретные таблицы/индексы/запросы оптимизировать
вот вот :) давно пора - это главное! и второй его совет про собиратель статистики postgresql тоже верен на все 100%, как правило такую работу делают после 1-2 месяцев работы с БД в production, так что если вы еще не делали - давно пора (только огромное кол-во индексов это тоже вредно - см. доки).
IO_support = 3 (32-bit w/sync) - вот это (цифра 3) иногда давало падение производительности на некотрых чипсетах, вообще, я редко встречал чипсеты которые требуют 3, как правило работает и 1, однако если это выставило само ядро при загрузке, тогда лучше или 0 или оставить 3, сам смотри как лучше будет.
А -m16 -a16 может помочь, или -m8 -a8 - это даже безопаснее...

saper ★★★★★
()
Ответ на: комментарий от anonymous

man man'ом, а вот сырец говорит:
/*
* Ugh.. this part looks ugly because we MUST set up
* the interrupt handler before outputting the first block
* of data to be written. If we hit an error (corrupted buffer list)
* in ide_multwrite(), then we need to remove the handler/timer
* before returning. Fortunately, this NEVER happens (right?).
*
* Except when you get an error it seems...
*
* MAJOR DATA INTEGRITY BUG !!! only if we error
*/

В любом случае никакого особого эффекта заметно небудет, сдается мне. Ну вот сейчас у меня в среднем 24 прерывания от диска в секунду (при том что среднесекундное число прерываний всего 500-1000),
ну будет не 24, а ~3. А остальные 500 так и останутся...

green ★★★★★
() автор топика

Опредленная оптимизация уже проделана и интересно узнать повысилась ли производительность? Green, можешь дать ответ?

Korwin ★★★
()
Ответ на: комментарий от Korwin

Производительность несомненно повысилась ;)
Кстати тут есть такие вот две функции которые время от времени зовутся и всем мешают (в смысле когда оно работает, все остальные select'ы в состоянии waiting), в них какие то циклы и выполняются они не очень быстро ;)
Есть ли возможность с ними что-нибудь проделать?

CREATE FUNCTION stat_update () RETURNS timestamp with time zone
    AS '
DECLARE
        top record;
        st1 int;
        st2 int;
        st3 int;
        st4 int;
        now timestamp;
BEGIN
        now=''now'';
        FOR top IN SELECT id FROM topics WHERE stat2!=0 FOR UPDATE LOOP
                SELECT count(*) INTO st1 FROM comments WHERE topic = top.id AND NOT deleted;
                SELECT count(*) INTO st2 FROM comments WHERE topic = top.id AND now-''3 day''::interval<postdate AND NOT deleted;
                SELECT count(*) INTO st3 FROM comments WHERE topic = top.id AND now-''1 day''::interval<postdate AND NOT deleted;
                SELECT count(*) INTO st4 FROM comments WHERE topic = top.id AND now-''1 hour''::interval<postdate AND NOT deleted;
                UPDATE topics SET stat1 = st1,stat2 = st2,stat3 = st3,stat4 = st4 WHERE id = top.id AND (stat1 != st1 OR stat2 != st2 OR stat3 != st3 OR stat4 != st4 );
        END LOOP;
        FOR top IN SELECT topic FROM votenames WHERE stat2!=0 FOR UPDATE LOOP
                SELECT count(*) INTO st1 FROM comments WHERE topic = top.topic AND NOT deleted;
                SELECT count(*) INTO st2 FROM comments WHERE topic = top.topic AND now-''3 day''::interval<postdate AND NOT deleted;
                SELECT count(*) INTO st3 FROM comments WHERE topic = top.topic AND now-''1 day''::interval<postdate AND NOT deleted;
                SELECT count(*) INTO st4 FROM comments WHERE topic = top.topic AND now-''1 hour''::interval<postdate AND NOT deleted;
                UPDATE votenames SET stat1 = st1,stat2 = st2,stat3 = st3,stat4 = st4 WHERE topic = top.topic;
        END LOOP;
        RETURN now;
END;
'
    LANGUAGE plpgsql;

и

CREATE FUNCTION stat_update2 () RETURNS timestamp with time zone
    AS '
DECLARE
        grp record;
        st1 int;
        st2 int;
        st3 int;
        st4 int;
        t1 int;
        t2 int;
        t3 int;
        t4 int;
        now timestamp;
BEGIN
        now=''now'';
        FOR grp IN SELECT id FROM groups WHERE stat2!=0 FOR UPDATE LOOP
                SELECT sum(stat1) INTO st1 FROM topics WHERE groupid = grp.id AND NOT deleted;
                SELECT sum(stat2) INTO st2 FROM topics WHERE groupid = grp.id AND NOT deleted;
                SELECT sum(stat3) INTO st3 FROM topics WHERE groupid = grp.id AND NOT deleted;
                SELECT sum(stat4) INTO st4 FROM topics WHERE groupid = grp.id AND NOT deleted;
                SELECT sum(stat4) INTO st4 FROM topics WHERE groupid = grp.id AND NOT deleted;
                SELECT count(*) INTO t1 FROM topics WHERE groupid = grp.id AND NOT deleted;
                SELECT count(*) INTO t2 FROM topics WHERE groupid = grp.id AND now-''3 day''::interval<postdate AND NOT deleted;
                SELECT count(*) INTO t3 FROM topics WHERE groupid = grp.id AND now-''1 day''::interval<postdate AND NOT deleted;
                SELECT count(*) INTO t4 FROM topics WHERE groupid = grp.id AND now-''1 hour''::interval<postdate AND NOT deleted;
                UPDATE groups SET stat1 = st1 + t1 ,stat2 = st2 + t2 ,stat3 = st3 + t3 ,stat4 = st4 + t4 WHERE id = grp.id AND ( stat1 != st1 + t1 OR stat2 != st2 + t2 OR stat3 != st3 + t3 OR stat4 != st4 + t4 );
        END LOOP;
        RETURN now;
END;
'
    LANGUAGE plpgsql;

green ★★★★★
() автор топика

ну, я бы предложил выкинуть из обеих процедур слова 'FOR UPDATE'. работать оно всё равно долго будет, но не будет при этом мешать работать всему остальному.

есть, наверное, и другие варианты, но поостерегусь предлагать их без тестирования. ;)

sad_spirit
()
Ответ на: комментарий от green


> ну будет не 24, а ~3. А остальные 500 так и останутся...

green, ты чем думаешь? multcount снижает количество I/O операций, снижает и оптимизирует нагрузку на твой не самый быстрый диск.

Ну подумаешь, 3 секунды читался большой кусок данных или 24 секунды. Вот так ты рассуждаешь. А комментарий в сырце - некоторые мысли/сомнения в слух. Там не говорится, что данный код бесполезен/неэффективен/не_имеет_смысла, как это пытаешься представить ты, ни разу не протестировав.

green, ты полный ламер.

anonymous
()

в man-е hdparm-а еще есть и такая фраза Some drives claim to support multiple mode, but lose data at some settings. Under rare circumstances, such failures can result in massive filesystem corruption. Оно конечно далеко не на всех винтах и случается крайне редко но тем не менее брать в расчет это надо, учитывая коментарии коду.

Еще интересно на каких операция multcount дает прирост? на потоковом чтении-записи или на множественно параллельном доступе? Вот мои результаты для потокового чтения: hdparm -m 16 /dev/hda

/dev/hda: setting multcount to 16 multcount = 16 (on)

hdparm -tT /dev/hda

/dev/hda: Timing buffer-cache reads: 128 MB in 0.97 seconds =131.96 MB/sec Timing buffered disk reads: 64 MB in 1.35 seconds = 47.41 MB/sec

hdparm -m 0 /dev/hda

/dev/hda: setting multcount to 0 multcount = 0 (off)

/dev/hda: Timing buffer-cache reads: 128 MB in 0.96 seconds =133.33 MB/sec Timing buffered disk reads: 64 MB in 1.39 seconds = 46.04 MB/sec

Видим некоторое замедление, но оно явно в пределах погрешности измерения. Может при одновременном доступе и есть выигрыш, но два одновременно запущенных hdparm-а показали туже картину (правда они наверняка читали из одной и той же области диска которая была закеширована :) )

anonymous
()
Ответ на: комментарий от anonymous

Думать надо головой! Количестко IO операций оно НЕ снижает. Оно снижает количество прерываний. И нагрузку оно не оптимизирует.
24 прерывания в секунду - это не значит что кусок читался 24 секунды ;) потому что сейчас просто 1 прерывание на кажные 512 байт, а будет 1 прерывание на ~4k

Насчет ни разу не протестировав - это ты загнул ;)

green ★★★★★
() автор топика
Ответ на: комментарий от anonymous

multicount дает не прирост, в современном мире multicount уменьшает число прерываний при последовательном обращении к данным длиной более 512 байт (до 8k).
Учитывая тот факт что большинство современных файлух работают с 4k блоксайзом, мы можем смело расчитывать на уменьшение irq-rate от винта примерно раз так в восемь, что все равно является каплей в море.

green ★★★★★
() автор топика
Ответ на: комментарий от anonymous

> а как он по надежности будет? бухгалтерию ему можно доверить?

Пля у меня термоядерная установка уже лет 5 на нем крутится, а ты со своей бухгалтерией мельтешишь...

anonymous
()

green, дай команду hdaprm -mXX /dev/hdY, где XX = номеру MaxMultSect, в свою очередь значение MaxMultSect ты сможешь узнать дав команду hdparm -i /dev/hda.

Здесь /dev/hda - твой диск.

У меня, например:

опции hdparm = -d1 -X udma5 -c3 -W1 -m16 -a16 -K1 -k1







anonymous
()

По поводу -m16 ... по умолчанию ядро ставит -a8, то есть будет читать блоками по 4096 байт(размер i-node в ext2/ext3 по умолчанию), поэтому чтобы ничего не нарушить и возможно получить прибавку в скорости лучше использовать -m8, тогда эти 8 секторов будут читаться за один такт (все равно стоит читать по 8 в опции -a8), вместо чтения по -a8 восьми секторов за 8 тактов... хотя конечно слово такт тут возможно и неуместно :)

Вывод: :))) hdparm -a8 -m8 -K1 -k1 /dev/hda погоды не испортит, а вот помочь может, или есть опасения? green why not? особенно если учесть, что и PostgreSQL все организовывает страницами по 4096 на x86 по умолчанию.

saper ★★★★★
()
Ответ на: комментарий от green


> Думать надо головой! Количестко IO операций оно НЕ снижает.

В голове тоже есть разные составляющие. Я думаю мозгами, а ты наверное носом. Если требуется прочитать 4k и это делается за одно прерывание. В твоем случае - 8. Соответственно - 8 операций I/O против одной.

anonymous
()
Ответ на: комментарий от saper

разве я недостаточно понятно в предыдущий раз об'яснил почему никакого заметного эффекта это не даст? ;)

Кстати я незнаю что ты подразумеваешь под размером i-node в ext2/3, видимо размер блока? ;)

-m я пробовал и я знаю что оно никакого выигрыша не дает. По крайней мере заметного невооруженным взглядом ;)

green ★★★★★
() автор топика
Ответ на: комментарий от anonymous

Не. Гм, похоже мы по разному понимаем что тако IO операция ;)

В моем понимании IO операция - это один запрос к драйверу блочного устройста. А уж насколько кусочков оно внутри себя ее разделит - неважно.

green ★★★★★
() автор топика
Ответ на: комментарий от green


> В моем понимании IO операция - это один запрос к драйверу

Хрен тебя знает, откуда ты это взял.

Я знаю такое определение:
Disk I/O is the act of retrieving and/or updating information stored on a disk drive or in a disk environment.

Нечто обобщенное, никакой жесткой привязки к драйверу. Но в
нашем контексте интересно знать, насколько уменьшаются прямые
обращения к физическому диску.

anonymous
()

2green про ту процедуру, что ты привел, нельзя ли:
1. Переписать на чистый SQL с использованием тех же TEMP TABLE? Известно, что SQL-функции зачастую работают на порядок быстрее PL/pgSQL, если это можно сделать без проблем.
2. Разбить ту PL/pgSQL функцию на куски (вроде 10 операций = 10 кусков), то есть будет 10 PL/pgSQL функций, и вызывать их скажем с интервалом в 10 минут, чтобы нагрузка на сервер была более плавной.
3. Самый сложный, но самый полезный IMHO вариант, вставить туда выдачу сообщений через RAISE NOTICE на каждом шаге (по сути через строчку кода), и выяснить на каком этапе больше всего времени заьрачивается, далее думать что делать с этим этапом (как его можно оптимизировать).

Кстати, хоть на быстром, хоть на медленном канале, я не замечал тормозов LOR, только изредка :)

saper ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.