Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
"HashAggregate (cost=1807.60..1807.62 rows=1 width=31)" " -> Nested Loop (cost=157.96..1806.29 rows=131 width=31)" " -> Nested Loop (cost=145.60..252.16 rows=1 width=23)" " -> Nested Loop Left Join (cost=145.60..243.52 rows=1 width=15)" " -> Bitmap Heap Scan on accanl (cost=145.60..235.24 rows=1 width=16)" " Recheck Cond: ((accanl_fund = 56537) AND ((accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[])) OR (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[]))))" " Filter: (((dateclose >= '2007-06-18'::date) AND (dateclose <= '2007-06-24'::date) AND (dateopen <= '2007-06-24'::date)) OR (dateclose IS NULL))" " -> BitmapAnd (cost=145.60..145.60 rows=23 width=0)" " -> Bitmap Index Scan on idx32 (cost=0.00..11.22 rows=395 width=0)" " Index Cond: (accanl_fund = 56537)" " -> BitmapOr (cost=134.12..134.12 rows=4675 width=0)" " -> Bitmap Index Scan on idx30 (cost=0.00..78.19 rows=2721 width=0)" " Index Cond: (accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[]))" " -> Bitmap Index Scan on idx31 (cost=0.00..55.93 rows=1954 width=0)" " Index Cond: (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[]))" " -> Index Scan using pkidx20 on locbranch (cost=0.00..8.27 rows=1 width=15)" " Index Cond: (accanl.idlocbranch = locbranch.id)" " -> Index Scan using idx_dia_1 on fvaluedia (cost=0.00..8.64 rows=1 width=8)" " Index Cond: (fvaluedia.idrow = accanl.id)" " Filter: ((idfeature = 749630) AND ((fvalue)::text <> ALL (('{Накопительный,"Счет КБК"}'::character varying[])::text[])) AND (idfeature IS NOT NULL))" " -> Bitmap Heap Scan on restanl (cost=12.37..1549.12 rows=400 width=24)" " Recheck Cond: (restanl.idaccanl = accanl.id)" " Filter: ((restanl_date >= '2006-12-24'::date) AND (restanl_date <= '2007-06-24'::date))" " -> Bitmap Index Scan on idx12 (cost=0.00..12.34 rows=400 width=0)" " Index Cond: (restanl.idaccanl = accanl.id)" Уважаемые знатоки - кто видит без бинокля, где тормоза? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2007, 16:56 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
А это сам запрос select charcod,sum(abs(turndeb)) as td,sum(abs(turncre)) as tc from restanl inner join accanl on (restanl.idaccanl=accanl.id) left join fvaluedia on (fvaluedia.idrow=accanl.id and fvaluedia.idfeature=749630 and fvaluedia.fvalue not in ('Накопительный','Счет КБК') ) left join locbranch on (accanl.idlocbranch=locbranch.id) where (restanl_date >='2006-12-24' and restanl_date <='2007-06-24') and accanl.accanl_fund=56537 and ((accanl.dateclose>='2007-06-18' and accanl.dateclose<='2007-06-24' and accanl.dateopen<='2007-06-24') or accanl.dateclose is null ) and ((accanl.accsin1 in ('401','402','403','404','405','406','407')) or (accanl.accsin2 in ('40802','40804','40805','40806','40807'))) and idfeature is not null group by accanl.id,charcod ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2007, 17:04 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
ignitor"HashAggregate (cost=1807.60..1807.62 rows=1 width=31)" ................. Уважаемые знатоки - кто видит без бинокля, где тормоза? Esli hotite chtoby vam pomogli, to !Vsegda! privodite vyvod EXPLAIN ANALYZE, a ne prosto EXPLAIN. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2007, 17:16 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Explain analyse делается до сих пор. Может что с настройками сервера не то? Посмотрите пожалуйста! ОЗУ 2ГБ, Intel Pentium Xeon 5110 1.6 Ghz "PostgreSQL 8.2.4 on i686-pc-mingw32, compiled by GCC gcc.exe (GCC) 3.4.2 (mingw-special)" listen_addresses = '*' max_connections = 50 shared_buffers = 256MB max_fsm_pages = 204800 wal_buffers = 256kB checkpoint_segments = 6 effective_cache_size = 512MB datestyle = 'iso, dmy' client_encoding = win1251 lc_messages = 'Russian_Russia.20866' lc_monetary = 'Russian_Russia.20866' lc_numeric = 'Russian_Russia.20866' lc_time = 'Russian_Russia.20866' остальное по дефаулту pg_config BINDIR = D:/POSTGR~1/bin DOCDIR = D:/POSTGR~1/doc INCLUDEDIR = D:/PostgreSQL/include PKGINCLUDEDIR = D:/PostgreSQL/include INCLUDEDIR-SERVER = D:/PostgreSQL/include/server LIBDIR = D:/POSTGR~1/lib PKGLIBDIR = D:/POSTGR~1/lib LOCALEDIR = D:/PostgreSQL/share/locale MANDIR = D:/PostgreSQL/man SHAREDIR = D:/POSTGR~1/share SYSCONFDIR = D:/PostgreSQL/etc PGXS = D:/PostgreSQL/lib/pgxs/src/makefiles/pgxs.mk CONFIGURE = '--with-openssl' '--with-perl' '--with-tcl' '--with-python' '--with-ldap' '--enable-nls' '--enable-thread-sa fety' '--with-krb5' '--with-includes=/mingw/include/krb5' CC = gcc CPPFLAGS = -I./src/include/port/win32 -DEXEC_BACKEND -I/mingw/include/krb5 -I../../../src/include/port/win32 CFLAGS = -O2 -Wall -Wmissing-prototypes -Wpointer-arith -Winline -Wdeclaration-after-statement -Wendif-labels -fno-stric t-aliasing CFLAGS_SL = LDFLAGS = -Wl,--allow-multiple-definition LDFLAGS_SL = LIBS = -lpgport -lintl -lssleay32 -leay32 -lcomerr32 -lkrb5_32 -lz -lm -lws2_32 -lshfolder VERSION = PostgreSQL 8.2.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2007, 17:50 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Когда последний раз делали VACUUM? -- signature -- Да кому он нужен этот 8-ой номер? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2007, 18:04 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
VACUUM делал непосредственно перед запросом, со всеми опциями и по всемм таблицам по отдельности. А чем плоха 8? В пятницу таже версия работала вполне прилично, но после переинициализации кластера и перезаливки данных началась эта вот беда. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2007, 18:09 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Решил индексы перестроить по самой большой таблице - ~9млн. записей. Что можно еще попробовать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2007, 18:34 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Как ни странно - вроде бы помогло. И explain analyse быстро сделался ... В чем дело было? "HashAggregate (cost=1807.51..1807.53 rows=1 width=31) (actual time=63507.914..63510.484 rows=2559 loops=1)" " -> Nested Loop (cost=157.87..1806.20 rows=131 width=31) (actual time=1363.869..62555.970 rows=335930 loops=1)" " -> Nested Loop (cost=145.60..252.16 rows=1 width=23) (actual time=1273.143..22599.875 rows=2559 loops=1)" " -> Nested Loop Left Join (cost=145.60..243.52 rows=1 width=15) (actual time=1242.048..18038.653 rows=2588 loops=1)" " -> Bitmap Heap Scan on accanl (cost=145.60..235.24 rows=1 width=16) (actual time=1242.036..17961.645 rows=2588 loops=1)" " Recheck Cond: ((accanl_fund = 56537) AND ((accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[])) OR (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[]))))" " Filter: (((dateclose >= '2007-06-18'::date) AND (dateclose <= '2007-06-24'::date) AND (dateopen <= '2007-06-24'::date)) OR (dateclose IS NULL))" " -> BitmapAnd (cost=145.60..145.60 rows=23 width=0) (actual time=1201.788..1201.788 rows=0 loops=1)" " -> Bitmap Index Scan on idx32 (cost=0.00..11.22 rows=395 width=0) (actual time=674.870..674.870 rows=60088 loops=1)" " Index Cond: (accanl_fund = 56537)" " -> BitmapOr (cost=134.12..134.12 rows=4675 width=0) (actual time=523.612..523.612 rows=0 loops=1)" " -> Bitmap Index Scan on idx30 (cost=0.00..78.19 rows=2721 width=0) (actual time=288.570..288.570 rows=3964 loops=1)" " Index Cond: (accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[]))" " -> Bitmap Index Scan on idx31 (cost=0.00..55.93 rows=1954 width=0) (actual time=235.035..235.035 rows=1382 loops=1)" " Index Cond: (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[]))" " -> Index Scan using pkidx20 on locbranch (cost=0.00..8.27 rows=1 width=15) (actual time=0.022..0.023 rows=1 loops=2588)" " Index Cond: (accanl.idlocbranch = locbranch.id)" " -> Index Scan using idx_dia_1 on fvaluedia (cost=0.00..8.64 rows=1 width=8) (actual time=1.422..1.759 rows=1 loops=2588)" " Index Cond: (fvaluedia.idrow = accanl.id)" " Filter: ((idfeature = 749630) AND ((fvalue)::text <> ALL (('{Накопительный,"Счет КБК"}'::character varying[])::text[])) AND (idfeature IS NOT NULL))" " -> Bitmap Heap Scan on restanl (cost=12.28..1549.03 rows=400 width=24) (actual time=8.325..15.473 rows=131 loops=2559)" " Recheck Cond: (restanl.idaccanl = accanl.id)" " Filter: ((restanl_date >= '2006-12-24'::date) AND (restanl_date <= '2007-06-24'::date))" " -> Bitmap Index Scan on idx12 (cost=0.00..12.25 rows=400 width=0) (actual time=6.814..6.814 rows=454 loops=2559)" " Index Cond: (restanl.idaccanl = accanl.id)" "Total runtime: 63511.947 ms" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2007, 18:42 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Ничего не понимаю - опять на том же запросе тормоза! Что делать? Где копать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2007, 20:02 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
INFO: vacuuming "public.restanl" INFO: "restanl": found 0 removable, 9084306 nonremovable row versions in 120132 pages DETAIL: 0 dead row versions cannot be removed yet. Nonremovable row versions range from 92 to 144 bytes long. There were 3625 unused item pointers. Total free space (including removable row versions) is 5976812 bytes. 0 pages are or will become empty, including 0 at the end of the table. 14504 pages containing 1433892 free bytes are potential move destinations. CPU 2.09s/0.96u sec elapsed 151.65 sec. INFO: index "idx12" now contains 9084306 row versions in 24911 pages DETAIL: 0 index row versions were removed. 0 index pages have been deleted, 0 are currently reusable. CPU 0.43s/2.32u sec elapsed 17.98 sec. INFO: index "idx13" now contains 9084306 row versions in 24911 pages DETAIL: 0 index row versions were removed. 0 index pages have been deleted, 0 are currently reusable. CPU 0.59s/2.57u sec elapsed 20.65 sec. INFO: "restanl": moved 0 row versions, truncated 120132 to 120132 pages DETAIL: CPU 0.06s/0.17u sec elapsed 4.65 sec. INFO: analyzing "public.restanl" INFO: "restanl": scanned 3000 of 120132 pages, containing 226845 live rows and 0 dead rows; 3000 rows in sample, 9083781 estimated total rows Total query runtime: 195294 ms. Сделал VACUUM FULL вроде опять нормально работает. Как часто надо вакуумить? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.06.2007, 20:14 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
VACUUM FULL - это круто. У меня VACUUM ANALYZE делается раз в сутки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2007, 03:56 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
постгрес ошибается в оценке кол-ва строк Код: plaintext Код: plaintext Код: plaintext из-за этого возможно выбирает не самый оптимальный план попробуйте собрать более точную статистику по нужным стобцам таблицы accanl с помощью команды vacuum analyze при большем значении переменной default_statistics_target=... или ALTER TABLE ... ALTER COLUMN ... SET STATISTICS ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2007, 09:57 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Действительно - после VACUUM ANALYSE на все таблицы, время выполнения запросов нормализовалось. Увеличил, как советовал Lexa NailBat default_statistics_target=100 (было 10) и тепер EXPLAIN ANALYSE выглядит так: "HashAggregate (cost=220558.29..220757.49 rows=9960 width=31) (actual time=5546.835..5549.301 rows=2559 loops=1)" " -> Hash Join (cost=48503.37..219759.84 rows=79845 width=31) (actual time=876.900..4610.365 rows=335930 loops=1)" " Hash Cond: (restanl.idaccanl = accanl.id)" " -> Bitmap Heap Scan on restanl (cost=39497.59..197495.42 rows=2507789 width=24) (actual time=673.133..2830.067 rows=2454083 loops=1)" " Recheck Cond: ((restanl_date >= '2006-12-24'::date) AND (restanl_date <= '2007-06-24'::date))" " -> Bitmap Index Scan on idx13 (cost=0.00..38870.64 rows=2507789 width=0) (actual time=659.848..659.848 rows=2454083 loops=1)" " Index Cond: ((restanl_date >= '2006-12-24'::date) AND (restanl_date <= '2007-06-24'::date))" " -> Hash (cost=8985.11..8985.11 rows=1654 width=23) (actual time=203.737..203.737 rows=2559 loops=1)" " -> Hash Left Join (cost=6518.51..8985.11 rows=1654 width=23) (actual time=88.428..201.204 rows=2559 loops=1)" " Hash Cond: (accanl.idlocbranch = locbranch.id)" " -> Hash Join (cost=6512.10..8972.02 rows=1654 width=24) (actual time=88.261..197.781 rows=2559 loops=1)" " Hash Cond: (fvaluedia.idrow = accanl.id)" " -> Bitmap Heap Scan on fvaluedia (cost=766.75..2923.08 rows=57410 width=8) (actual time=14.131..91.067 rows=56636 loops=1)" " Recheck Cond: (idfeature = 749630)" " Filter: ((fvalue)::text <> ALL (('{Накопительный,"Счет КБК"}'::character varying[])::text[]))" " -> Bitmap Index Scan on idx_dia_3 (cost=0.00..752.40 rows=57619 width=0) (actual time=13.754..13.754 rows=56981 loops=1)" " Index Cond: (idfeature = 749630)" " -> Hash (cost=5724.59..5724.59 rows=1660 width=16) (actual time=74.103..74.103 rows=2588 loops=1)" " -> Bitmap Heap Scan on accanl (cost=121.26..5724.59 rows=1660 width=16) (actual time=3.530..71.210 rows=2588 loops=1)" " Recheck Cond: ((accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[])) OR (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[])))" " Filter: ((accanl_fund = 56537) AND (((dateclose >= '2007-06-18'::date) AND (dateclose <= '2007-06-24'::date) AND (dateopen <= '2007-06-24'::date)) OR (dateclose IS NULL)))" " -> BitmapOr (cost=121.26..121.26 rows=5788 width=0) (actual time=2.609..2.609 rows=0 loops=1)" " -> Bitmap Index Scan on idx30 (cost=0.00..91.52 rows=4768 width=0) (actual time=1.806..1.806 rows=3313 loops=1)" " Index Cond: (accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[]))" " -> Bitmap Index Scan on idx31 (cost=0.00..28.91 rows=1021 width=0) (actual time=0.800..0.800 rows=1110 loops=1)" " Index Cond: (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[]))" " -> Hash (cost=6.34..6.34 rows=6 width=15) (actual time=0.137..0.137 rows=6 loops=1)" " -> Index Scan using pkidx20 on locbranch (cost=0.00..6.34 rows=6 width=15) (actual time=0.121..0.127 rows=6 loops=1)" "Total runtime: 5551.442 ms" И еще вопрос до кучи - стоит ли использовать autovacuum=on или же лучше поставить в ежедневную задачу VACUUM ANALYSE ночью? Особенностью базы является то, что большинство таблиц удаляются, затем создаются вновь, заливаются данными через COPY, затем строятся индексы. Таблицы по 3-12млн. активно обновляются в течение дня, идет удаление 18-50 тысяч записей и затем через COPY заливаются обратно. Какой вариант мне подходит больше? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2007, 10:38 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
ignitorТаблицы по 3-12млн. активно обновляются в течение дня, идет удаление 18-50 тысяч записей и затем через COPY заливаются обратно. Какой вариант мне подходит больше?если есть возможность провести analyze именно этой таблицы сразу после массовой операции удаления - почему бы его не произвесть? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2007, 11:06 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
ignitordefault_statistics_target=100 (было 10) и тепер EXPLAIN ANALYSE выглядит такда, теперь вроде бы все нормально ignitorИ еще вопрос до кучи - стоит ли использовать autovacuum=on или же лучше поставить в ежедневную задачу VACUUM ANALYSE ночью? Особенностью базы является то, что большинство таблиц удаляются, затем создаются вновь, заливаются данными через COPY, затем строятся индексы.наверное надо или а) включить autovacuum, или б) делать vacuum, analyze после каждого массированного обновления таблицы ignitorТаблицы по 3-12млн. активно обновляются в течение дня, идет удаление 18-50 тысяч записей и затем через COPY заливаются обратно. Какой вариант мне подходит больше?36-100 тысяч строк для таблицы из 3-12 миллионов составляют 1 процент, то есть их изменение не является массированным обновлением таблицы, имхо поэтому vacuum, analyze после каждого такого изменения не обязательны LeXa NalBat Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2007, 12:39 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
assa...провести analyze именно этой таблицы... Так я и сделаю. А autovacuum все же отключать или оставить в on? Обновлениями данных в базе занимается только 1 процесс, остальные пользователи только читают (строят отчеты). Может заодно кто-нибудь посоветует какие параметры в postgresql.conf покрутить для оптимизации под тяжелые запросы для множества пользователей? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2007, 12:41 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat ... 36-100 тысяч строк для таблицы из 3-12 миллионов составляют 1 процент, то есть их изменение не является массированным обновлением таблицы, имхо поэтому vacuum, analyze после каждого такого изменения не обязательны ... Обратил внимание на странную вещь - раньше, когда я вставлял записи при помощи INSERT, действительно эти обновления никак не отражались на выполнении запросов. Стоило мне поменять стратегию загрузки - сначала в текст, потом COPY в таблицу - даже 5 таких вставок по 18 тысяч записей приводят к тому, что EXPLAIN ANALYSE уходит в себя и не возвращается. После VACUUM ANALYSE все приходит в норму. Это особенность COPY? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.06.2007, 15:24 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Еще вопрос: есть две таблицы CREATE TABLE accanl ( id bigint, idclient bigint, acc_char character(1), accanl_pic character(25), accsin1 character(3), accsin2 character(5), accanl_area bigint, accanl_branch bigint, accanl_fund bigint, dateopen date, dateclose date, datechange date, datefirstpay date, accanl_name character(160), idlocbranch bigint, note character(640), accsort character(25) ) WITHOUT OIDS; 57679 записей и CREATE TABLE linkdia ( f_parentid bigint, f_childid bigint, f_selector bigint, f_linkid bigint ) WITHOUT OIDS; 153722 записи explain analyse update accanl set idlocbranch=(select f_childid from linkdia where f_parentid=accanl.id and f_selector=1 and f_linkid=3) "Seq Scan on accanl (cost=100000000.00..101861149.41 rows=115019 width=3526) (actual time=0.076..541.220 rows=57679 loops=1)" " SubPlan" " -> Index Scan using part_idx_1 on linkdia (cost=0.00..16.03 rows=1 width=8) (actual time=0.004..0.004 rows=0 loops=57679)" " Index Cond: (f_parentid = $0)" "Total runtime: 216345.747 ms" Что-то мне подсказывает, что так долго выполняться не должно. Запрос дурной? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.06.2007, 08:59 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
запрос переписал, но все равно както долго мне кажется: explain analyse update accanl set idlocbranch=(select f_childid from linkdia where f_parentid=accanl.id and f_selector=1 and f_linkid=3) where accanl.id in (select f_parentid from linkdia where (f_selector=1 and f_linkid=3)) "Nested Loop (cost=293.61..1307.01 rows=114 width=987) (actual time=1927.222..29509.066 rows=1584 loops=1)" " -> HashAggregate (cost=293.61..295.12 rows=151 width=8) (actual time=7.663..10.071 rows=1584 loops=1)" " -> Index Scan using part_idx_1 on linkdia (cost=0.00..292.85 rows=302 width=8) (actual time=0.068..6.062 rows=1584 loops=1)" " -> Index Scan using idx1 on accanl (cost=0.00..3.46 rows=1 width=987) (actual time=18.601..18.605 rows=1 loops=1584)" " Index Cond: (accanl.id = linkdia.f_parentid)" " SubPlan" " -> Index Scan using part_idx_1 on linkdia (cost=0.00..4.28 rows=1 width=8) (actual time=0.008..0.009 rows=1 loops=1584)" " Index Cond: (f_parentid = $0)" "Total runtime: 38507.027 ms" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.06.2007, 09:27 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
очень медленно работает этот индекс, попробуйте его пересоздать Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.06.2007, 10:35 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
У тебя две проблемы, а не одна. Но одну тебе помогли решить. Еще проверяй, сколько места занимают индексы - постгрес версионник, это приводит к некоторым последствиям, которые надо учитывать. Например, при обновлении малого числа записей таблицы можно получить кучу мусора. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.06.2007, 21:17 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
MBG...Еще проверяй, сколько места занимают индексы ... Ну допустим проверил я сколько у меня места индексы занимают - как это мне может помочь? Вот статистика по самой большой таблице SELECT relname AS name, relfilenode AS oid, relpages as size_in_pages , reltuples::numeric as count FROM pg_class WHERE relname NOT LIKE 'pg%' ORDER BY relpages DESC; name oid size_in_pages reltuples "docblc" 16714 700088 3801970 "didx1" 25917 12075 3801970 "didx2" 25921 12946 3801970 "didx3" 25922 29130 3801970 "didx4" 25923 12737 3801970 "didx5" 25924 12647 3801970 И еще - нашел вот такой совет: "Иногда, особенно для интенсивно обновляемых таблиц, начинают сыпаться deadlock'и и VACUUM выполняется нереально долгое время. Часто проблема из-за поврежденного индекса. Решение: REINDEX TABLE таблица; REINDEX INDEX индекс;" я всегда думал, что REINDEX TABLE предполагает, что индексы к этой таблице так же переиндексируются - это не так? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2007, 11:56 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Дело в том, что версионность данных приводит к существованию индексов на все версии данных. Удаленные или измененные данные тоже имеют индексы, иногда это приводит к взрывообразному росту индексов, например на таблице 100 мегабайт индексы могут вырасти в десятки гигабайт (зависит от методологии работы с данными, разумеется). Вот тут и начинаются развлечения :-) Оптимальный вариант - перепроектировать приложение. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2007, 15:16 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
ignitorВот статистика по самой большой таблице name oid size_in_pages reltuples "docblc" 16714 700088 3801970 "didx1" 25917 12075 3801970 "didx2" 25921 12946 3801970 "didx3" 25922 29130 3801970 "didx4" 25923 12737 3801970 "didx5" 25924 12647 3801970И? :-) Зачем смотреть статистику на "самую большую таблицу" docblc, если у вас тормозит индекс idx1 по таблице accanl? ignitorя всегда думал, что REINDEX TABLE предполагает, что индексы к этой таблице так же переиндексируются - это не так?Судя по доке - это так. MBGпри обновлении малого числа записей таблицы можно получить кучу мусора.Думаю, что при обновлении малого числа записей можно получить мало мусора, а не кучу. MBGУдаленные или измененные данные тоже имеют индексыНет, удаленные строки индекса помечаются как пригодные для использования командой vacuum. 22.1. Routine Vacuuming"lazy vacuum" or just VACUUM, marks expired data in tables and indexes for future reuse MBGиногда это приводит к взрывообразному росту индексов, например на таблице 100 мегабайт индексы могут вырасти в десятки гигабайтИз-за того что никогда не вызывается vacuum или reindex, или из-за описанного ниже эффекта? 22.2. Routine Reindexingif all but a few index keys on a page have been deleted, the page remains allocated. So a usage pattern in which all but a few keys in each range are eventually deleted will see poor use of space. MBGОптимальный вариант - перепроектировать приложение.Проще регулярно вызывать vacuum и reindex. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2007, 15:46 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat MBGОптимальный вариант - перепроектировать приложение.Проще регулярно вызывать vacuum и reindex. Если вызывать И vacuum И reindex, мусор будет чиститься, но на огромных таблицах выполняется долго. Лучше данные записать во временную таблицу, там обработать и переложить в большую таблицу. А на временную таблицу индексы обычно не нужны, так как обрабатываются все загруженные записи (а иначе зачем их грузить). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.06.2007, 21:11 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
2 MBG Как к ситуации автора топика ignitorТаблицы по 3-12млн. активно обновляются в течение дня, идет удаление 18-50 тысяч записей и затем через COPY заливаются обратно.можно применить ваш способ MBGЛучше данные записать во временную таблицу, там обработать и переложить в большую таблицу.Объясните пожалуйста подробнее. PS: "Перепроектирование приложения" - это, мне кажется, более широкое понятие, чем добавление в узких местах временных таблицы. Например, изменить структуру таблиц, при этом возможно даже изменив функционал базы, и как следствие приложения. Это может привести к кардинальному ускорению работы с бд. Но требует гораздо больших усилий со стороны программистов, чем routine vacuum reindex. :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2007, 09:31 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Попробую внести ясность. База является отражением набора таблиц системы Diasoft Bank 4x4 (если кто знает). Данные в таблицах обновляются 2 раза в день (иногда чаще). После некоторых экспериментов пришел к выводу, что самое быстрое - делать DROP TABLE, затем CREATE TABLE и COPY из файла. Однако не для всех таблиц - таблицу остатков по счетам за 6 лет работы не загрузишь за 10 минут. Поэтому по огромным таблицам идет то самое удаление и вставка. А вот таблица accanl как раз таки пересоздается каждый раз, поэтому в чем тормоза - непонятно. Хотя после включения в код VACUUM FULL ANALYSE accanl (выполняется 10,5 секунд) все вроде бы устаканилось. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2007, 11:02 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat2 MBG Как к ситуации автора топика ignitorТаблицы по 3-12млн. активно обновляются в течение дня, идет удаление 18-50 тысяч записей и затем через COPY заливаются обратно.можно применить ваш способ MBGЛучше данные записать во временную таблицу, там обработать и переложить в большую таблицу.Объясните пожалуйста подробнее. Если требуется проводить какие-то операции update, то только во временной таблице. Если просто удаление/добавление данных, то разделенные таблицы. Повесить по таймеру вакуум тех таблиц, которые обновляются, с интервалом в несколько часов (подобрать так, чтобы мусора много не успевало накопиться и вакуум выполнялся быстро и не мешал работе). P.S. Прямая работа с цельными таблицами порядка 10 миллионов записей весьма неэффективна и позволяет предположить мощное железо. Думаю, проблема замедления та же, что и в соседнем топике. Подробности см. http://sql.ru/forum/actualthread.aspx?tid=213801 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2007, 12:20 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
С большим интересом прочитал про разделенные таблицы. Если я разобъю свои большие таблицы, то до какой степени детализации это будет эффективно? Т.е. порядок частей таблицы не влияет на быстродействие? Или частить надо, но без фанатизма? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2007, 13:07 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
ignitorПосле некоторых экспериментов пришел к выводу, что самое быстрое - делать DROP TABLE, затем CREATE TABLE и COPY из файла... А вот таблица accanl как раз таки пересоздается каждый раз, поэтому в чем тормоза - непонятно. Хотя после включения в код VACUUM FULL ANALYSE accanl (выполняется 10,5 секунд) все вроде бы устаканилось.Мы делаем так DROP TABLE, COPY FROM, CREATE INDEX, VACUUM ANALYZE. Ключик FULL в команде VACUUM для только что созданной таблицы лишний. MBGЕсли требуется проводить какие-то операции update, то только во временной таблице.Не понятно, чем здесь сможет помочь временная таблица. Например, есть таблица (id,name,info,shows,clicks) с N записями. Необходимо для N/10 записей обновить по ключу id поля shows и clicks, по данным приходящим извне. Временная таблица? MBGЕсли просто удаление/добавление данных, то разделенные таблицы.Зачем? Чтобы операция массированного удаления/добавления затронула одну или несколько из разделенных таблиц? Но не всегда удастся разделить таблицы таким образом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2007, 13:18 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
ignitorС большим интересом прочитал про разделенные таблицы. Если я разобъю свои большие таблицы, то до какой степени детализации это будет эффективно? Т.е. порядок частей таблицы не влияет на быстродействие? Или частить надо, но без фанатизма? См. в блоге: "Например, можно создавать подтаблицу на каждый календарный месяц, тогда месячные отчеты будут обращаться лишь к одной таблице (бывают исключения, когда требуется обрабатывать и старые данные, но это уже повод создавать некоторые дополнительные таблицы и строить отчеты уже по ним)." Я разбиваю таблицы по месяцам, так как в месяц у меня планируется порядка 10 миллионов записей. Остальное довожу до ума кластеризацией. Если в месяц данных значительно больше, то надо думать и пробовать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2007, 13:42 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat MBGЕсли требуется проводить какие-то операции update, то только во временной таблице.Не понятно, чем здесь сможет помочь временная таблица. Например, есть таблица (id,name,info,shows,clicks) с N записями. Необходимо для N/10 записей обновить по ключу id поля shows и clicks, по данным приходящим извне. Временная таблица? Если несколько запросов _одновременно_ обновляют данные, используя транзакции, постгрес создает снимки таблицы для каждой транзакции и на них выполняет обновление, что очень неэффективно на больших таблицах. Даже при однопользовательском доступе можно напороться на грабли с тем, что одна транзакция еще не завершилась, а следующая началась. Например, база в 10 мегабайт может при интенсивном обновлении (раз в несколько минут) небольшим количеством данных вырасти до десяти гигабайт за сутки. Сборщик мусора в таких условиях не может эффектиивно работать - незафиксированные снимки таблицы не чистятся, индексы пухнут. LeXa NalBat MBGЕсли просто удаление/добавление данных, то разделенные таблицы.Зачем? Чтобы операция массированного удаления/добавления затронула одну или несколько из разделенных таблиц? Но не всегда удастся разделить таблицы таким образом. Неважно, сколько таблиц затронет обновление. Разница будет в _скорости выборки после_ этих операций (к вопросу о количестве дисковых операций). Разделять нужно, ориентируясь на селекты, а не на обновления. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2007, 13:53 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
MBG LeXa NalBat MBGЕсли требуется проводить какие-то операции update, то только во временной таблице.Не понятно, чем здесь сможет помочь временная таблица. Например, есть таблица (id,name,info,shows,clicks) с N записями. Необходимо для N/10 записей обновить по ключу id поля shows и clicks, по данным приходящим извне. Временная таблица?Если несколько запросов _одновременно_ обновляют данные, используя транзакции, постгрес создает снимки таблицы для каждой транзакции и на них выполняет обновление, что очень неэффективно на больших таблицах. Даже при однопользовательском доступе можно напороться на грабли с тем, что одна транзакция еще не завершилась, а следующая началась. Например, база в 10 мегабайт может при интенсивном обновлении (раз в несколько минут) небольшим количеством данных вырасти до десяти гигабайт за сутки. Сборщик мусора в таких условиях не может эффектиивно работать - незафиксированные снимки таблицы не чистятся, индексы пухнут.И? В этом случае сможет помочь временная таблица? Объясните пожалуйста подробнее. MBGРазница будет в _скорости выборки после_ этих операций (к вопросу о количестве дисковых операций). Разделять нужно, ориентируясь на селекты, а не на обновления.Неужели действительно скорость селектов по целой и партиционной таблице будет отличаться например более чем в два раза? Надо попробовать поэкспериментировать... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2007, 14:59 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Допустим побил я таблицу по месяцам, а у меня запрос обращается к данным на стыке месяцев или за полугодие - в этом случае партионность также эффективна? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2007, 15:05 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
LeXa NalBatОбъясните пожалуйста подробнее. Заливаем данные во временную таблицу, выполняем их обработку, копируем в постоянную таблицу, временная таблица (temp table) автоматически удаляется. Запуск сборщика мусора после этого не нужен - файлы временных таблиц удаляются целиком, чистить нечего. Если нужно заливать данные в один поток (например, когда разные клиенты могут заливать одни и те же данные, а мы хотим защититься от дубликатов и сообщить клиентам, какая часть их данных уже присутствует) создается постоянная таблица, которая блокируется на время заливки/обработки/удаления данных. Эффект тот же. LeXa NalBat MBGРазница будет в _скорости выборки после_ этих операций (к вопросу о количестве дисковых операций). Разделять нужно, ориентируясь на селекты, а не на обновления.Неужели действительно скорость селектов по целой и партиционной таблице будет отличаться например более чем в два раза? Надо попробовать поэкспериментировать... Пример: есть разделенная по месяцам таблица с данными за два года (24 части). Построение отчета за месяц выполняется как минимум на порядок быстрее. Особенно заметно тогда, когда в оперативке кэшируется лишь малая часть данных базы, например, база 10 Гб при оперативке 256 Мб. Если кто удивится, что по современным масштабам памяти немного, замечу, что для _одновременной работы_ с такой базой 10-ти пользователей больше и не нужно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2007, 15:18 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
ignitorДопустим побил я таблицу по месяцам, а у меня запрос обращается к данным на стыке месяцев или за полугодие - в этом случае партионность также эффективна? Конечно. Разбиение таблиц эффективно, если данные берутся не из всех таблиц. Например, имеем 24 таблицы по месяцам, при построении отчета за полугодие потребуется просмотреть лишь 6 таблиц, а не все данные. Если выбираем данные "на стыке месяцев", то надо просмотреть лишь 2 таблицы из 24. Плюс к тому, операционка будет кэшировать файлы часто используемых таблиц, в то время как на файл одной огромной таблицы не хватит памяти, поэтому даже при выборке _всех_ данных разделенные таблицы могут дать прирост производительности (выигрыш бывает и неожиданно большим, от запроса зависит). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2007, 15:25 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Большое спасибо всем кто поучаствовал в обсуждении моих проблем! Обязательно сообщу после перезаливки данных прирост производительности. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2007, 15:31 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
MBGЗаливаем данные во временную таблицу, выполняем их обработку, копируем в постоянную таблицу, временная таблица (temp table) автоматически удаляется. Запуск сборщика мусора после этого не нужен - файлы временных таблиц удаляются целиком, чистить нечего.Теперь кажется понятно, что под фразой "если требуется проводить какие-то операции update, то только во временной таблице" вы имели в виду, что надо проводить все предварительные расчеты используя временные таблицы. Я же предполагал, что все предварительные расчеты проведены клиентом, а под "операциями update" вы имели в виду именно обновление постоянной таблицы, а не добавление (как вы написали выше "копируем в постоянную таблицу"); при обновлении мусор (в постоянной таблице) образуется. :-( Мне кажется, что описание автора топика "таблицы по 3-12млн. активно обновляются в течение дня, идет удаление 18-50 тысяч записей и затем через COPY заливаются обратно" описывает алгоритм "delete returning" -> приложение (пересчет данных) -> "copy to", то есть временные таблицы здесь бесполезны. MBGЕсли нужно заливать данные в один поток (например, когда разные клиенты могут заливать одни и те же данные, а мы хотим защититься от дубликатов и сообщить клиентам, какая часть их данных уже присутствует) создается постоянная таблица, которая блокируется на время заливки/обработки/удаления данных.Блокировать можно и саму постоянную таблицу с помощью команды lock table, но конкурентность приложения от этого может сильно ухудшиться. :-( MBGПример: есть разделенная по месяцам таблица с данными за два года (24 части). Построение отчета за месяц выполняется как минимум на порядок быстрее.Интересно, за счет чего такая разница. Кажется, что безусловный seq scan по партиционной таблице против bitmap index scan по полной таблице конечно должен выигрывать, но не на порядок. Если не сложно, вы могли бы привести explain analyze этих двух запросов. MBGНапример, имеем 24 таблицы по месяцам, при построении отчета за полугодие потребуется просмотреть лишь 6 таблиц, а не все данные.Бред. Что по парционным таблицам, что по полной таблице, нужно просмотреть одинаковое количество tuples. При этом количество страниц, на которых они располагаются, может оказаться сильно разным, а может и примерно одинаковым. "Все данные" в большой таблице просматривать не обязательно, ведь кроме seq scan придумали index scan и bitmap index scan. :-) MBGПлюс к тому, операционка будет кэшировать файлы часто используемых таблиц, в то время как на файл одной огромной таблицы не хватит памяти.Бред. Операционка кэширует не файлы, а страницы! Ей фиолетово, являются ли эти страницы кусочками большого файла или маленьких. :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2007, 18:07 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Что касается индексирования, партишионирования и кластеризации - это вещи must have, которыми должен пользоваться каждый разработчик. Если архитектура СУБД разрабатывается с учетом этого, производительность получается на высоком уровне. Прикручивать к существующей базе сложнее, но тоже вполне выполнимо. P.S. На форум захожу эпизодически, а в остальное время с удовольствием пообщаюсь на подобные темы вот здесь: http://postgrestips.blogspot.com Это на тот случай, если вдруг появятся вопросы лично ко мне :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2007, 18:17 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Отвечаю LeXa NalBat: если обновления данных проводить в огромной таблице, кластеризация бесполезна, все равно будет непрерывная сегментация данных вследствии обновлений (update/delete/insert), в то время как обновление одной или двух подтаблиц разделенной таблицы пользуется всеми выгодами кластеризации и отсутствия мусора во всех остальных подтаблицах. Подумайте в этом направлении. Также есть разница в приоритетах кэширования изменяемых и постоянных данных операционной системой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.07.2007, 18:31 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
MBGЧто касается индексирования, партишионирования и кластеризации - это вещи must have, которыми должен пользоваться каждый разработчик.К сожалению, да. В идеале хотелось бы, чтобы СУБД сама об этом заботилась, а разработчик отдыхал. :-) MBGЕсли архитектура СУБД разрабатывается с учетом этого, производительность получается на высоком уровне.Однако не в каждой БД это необходимо делать. Мы, например, пока обходимся без партиционирования и кластеризации. MBGесли обновления данных проводить в огромной таблице, кластеризация бесполезна, все равно будет непрерывная сегментация данных вследствии обновленийВозможно, я опять неправильно понял вашу мысль, точнее сказать, почти ничего не понял. Уверен, что кластеризация огромной таблицы может оказаться очень полезной. MBGв то время как обновление одной или двух подтаблиц разделенной таблицы пользуется всеми выгодами кластеризацииНе согласен. Кластеризация одинаково полезна, как для частичных "больших" таблиц, так и для одной "огромной" таблицы. MBGесть разница в приоритетах кэширования изменяемых и постоянных данных операционной системойВ любой операционной системе? Киньте пожалуйста ссылки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2007, 10:53 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
"Кластеризация бесполезна" подразумевает, что в тех случаях, когда в таблице много изменяющихся данных, кластеризация будет только время отнимать. В идеальном случае, когда данные совсем не меняются, кластеризация наиболее эффективна. На практике можно сделать так, чтобы данные в части таблиц не менялись, для них кластеризация наиболее эффективна, а для изменяющихся таблиц эффективность ниже, поскольку сегментация данных все-таки есть, в той или иной степени (зависит от конкретного случая). По поводу кэширования ссылок не приведу, замечу лишь, что кэшируются _часто_ используемые данные. Те данные, которые не меняются, имеют большее число обращений в течении своей "жизни" (просто в силу большей ее продолжительности), чем быстро меняющиеся, что приводит к лучшему кэшированию именно постоянных данных. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2007, 11:12 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
MBG"Кластеризация бесполезна" подразумевает, что в тех случаях, когда в таблице много изменяющихся данных, кластеризация будет только время отнимать.Теперь понятно. Полностю с этим согласен. Просто из вашей фразы "если обновления данных проводить в огромной таблице, кластеризация бесполезна" не было понятно, в этой огромной таблице обновляется много данных или мало. В первом случае кластеризация менее эффективна, возможно и бесполезна, а во втором может оказаться очень эффективной и полезной. MBGПо поводу кэширования ссылок не приведу, замечу лишь, что кэшируются _часто_ используемые данные. Те данные, которые не меняются, имеют большее число обращений в течении своей "жизни" (просто в силу большей ее продолжительности), чем быстро меняющиеся, что приводит к лучшему кэшированию именно постоянных данных.Я не спец по осям. Имхо, предположение "кэшируются часто используемые данные" абсолютно верное, а вот вывод "приводит к лучшему кэшированию именно постоянных данных" вы сделали неправильный. В памяти создается новая (измененная или добавленная) версия данных, происходит commit, записывается на диск. Ведь затем эти данные из памяти не очищаются, они остаются закэшированными. Хотя это суть обновленные данные, а не постоянные. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2007, 11:42 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat В памяти создается новая (измененная или добавленная) версия данных, происходит commit, записывается на диск. Ведь затем эти данные из памяти не очищаются, они остаются закэшированными. Хотя это суть обновленные данные, а не постоянные. 'commit' - это на уровне базы данных, а не операционки. В самой базе в первую очередь кэшируются часто используемые данные, а не последние записанные - скорее, последние прочитанные. А операционка как закэшировала страницы с предыдущей версией данных, так и будет их держать в кэше, пока не заменит какими-то другими страницами - ведь старая версия данных на диске остается до сборки мусора, откуда ОСь знает, что это старая версия, об этом знает только база данных. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2007, 12:08 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
MBG'commit' - это на уровне базы данных, а не операционкиДа, но именно при commit-е происходит flush на диск. (Зависит от wal_sync_method.) MBGВ самой базе в первую очередь кэшируются часто используемые данные, а не последние записанные - скорее, последние прочитанные.Откуда такая информация? Что вообще есть кэш самой базы данных? Какими параметрами постгреса настраивается? MBGА операционка как закэшировала страницы с предыдущей версией данных, так и будет их держать в кэшеВерно. А наряду с ними в кэше будет держать страницы с новыми версиями данных. MBGоткуда ОСь знает, что это старая версияПравильно, не знает. Поэтому ОС будет какое-то время держать эти уже ненужные данные в кэше. До тех пор пока не пройдет время N, в течение которого к этим данным никто не обращался, ОС посчитает их неиспольуемыми и сможет заменить их в кэше другими данными. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2007, 12:58 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Кажется, мы немного о разном. Я рассматриваю случай, когда оперативная память составляет порядка несколько процентов от объема базы. Тут уже нет смысла говорить о кэшировании "и старых и новых страниц", просто негде их кэшировать. PostgreSQL в таких условиях пожалуй оптимальный выбор, может работать с гигантскими базами и слабо зависеть от объема доступной оперативной памяти. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2007, 13:18 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
LeXa NalBatименно при commit-е происходит flush на диск. (Зависит от wal_sync_method.) Не согласен. Если настройки базы заставляют каждую единичную операцию сразу писать на диск, производительность будет плачевной. Обычно записывается сразу пакет изменений. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2007, 13:21 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
MBGКажется, мы немного о разном. Я рассматриваю случай, когда оперативная память составляет порядка несколько процентов от объема базы. Тут уже нет смысла говорить о кэшировании "и старых и новых страниц", просто негде их кэшировать.Мы говорим об одном и том же. Разница количественная (объем оперативной памяти), но не качественная (алгоритм кэширования). То есть просто время N устаревания неиспользуемой информации в кэше, о котором я говорил, при меньшем доступном объеме оперативной памяти будет меньшим. MBGОбычно записывается сразу пакет изменений.Как именно это можно сделать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2007, 13:40 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.07.2007, 13:57 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
нужен совет - в субботу-воскресение буду перезаливать данные по большим таблицам с разделением по месяцам. Месяцев будет 41 на каждую таблицу. План такой - создаю временную таблицу name_table_ b r к ней 41 со всеми правилами и так для всех больших таблиц. Заливаю данные и после проверки "что_все_работает", переименовываю родительские таблицы в name_table. Следует ли для каждой таблицы пересоздавать\изменять правила или при переименовании родительской таблицы PG сам сделает все что нужно? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.07.2007, 10:11 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
В постгресе зависимости между объектами по уникальным идентификаторам этих объектов записываются, соответственно, на изменение имени таблицы постгресу чихать, все будет работать. Тем не менее, желательно отказаться от хранения всего в схеме public и создать схемы для данных. Например, в схеме data можно хранить "сырые" данные, а в схеме "cache" таблицы функционалов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.07.2007, 12:40 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
ignitorСледует ли для каждой таблицы пересоздавать\изменять правила или при переименовании родительской таблицы PG сам сделает все что нужно?не надо, постгрес сделает это сам Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. MBG http://oc.cs.msu.su/club/html/node2.html#SECTION00022000000000000000 Насколько я понял по этому посту , настройками wal от записи на диск по каждому коммиту не избавиться, потому что данные на диск все-таки будут записываться, но не в таблицу, а в лог. MBGжелательно отказаться от хранения всего в схеме public и создать схемы для данных. Например, в схеме data можно хранить "сырые" данные, а в схеме "cache" таблицы функционалов.Не в каждой БД непременно нужно раскидывать структуру по схемам. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.07.2007, 14:18 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
LeXa NalBatНасколько я понял по этому посту , настройками wal от записи на диск по каждому коммиту не избавиться, потому что данные на диск все-таки будут записываться, но не в таблицу, а в лог. В общем да. Но дело в том, что записать в лог соответствующее событие не требует каких-то трудоемких операций, это ведь не обновление данных в таблицах. В отличие от оракла, постгрес работает со своими данными через файловую систему, которая (линукс) тоже умеет кэшировать и делает это здорово. Так что если беспокоит именно файловый ввод/вывод, нужно настраивать на уровне файловой системы. Если уж так интересует этот вопрос, для начала можно noatime опцию для ФС выставить, должно помочь именно для множества мелких транзакций. А лучше научиться пользоваться двухфазными транзакциями и не заморачиваться на оптимизацию низкоуровневых операций. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.07.2007, 16:54 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
И еще вопрос - что быстрее для операции SELECT? Составной индекс CREATE INDEX rest_idx_3 ON restdepcrd USING btree (rest_date, accanl_pic); или 2 индекса CREATE INDEX rest_idx_3_1 ON restdepcrd USING btree (rest_date); CREATE INDEX rest_idx_3_2 ON restdepcrd USING btree (accanl_pic); ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.07.2007, 17:07 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Составной быстрее, поскольку не требует лишних вычислений и плюс к тому занимает физически меньше места. Но с появлением bitmap index scan не стоит без нужды прибегать к составным индексам. Разве чтобы order by ускорить. Сам составными индексами перестал пользоваться с появлением bitmap индексов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.07.2007, 17:20 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
MBG LeXa NalBat MBG LeXa NalBatименно при commit-е происходит flush на диск. (Зависит от wal_sync_method.)Не согласен. Если настройки базы заставляют каждую единичную операцию сразу писать на диск, производительность будет плачевной. Обычно записывается сразу пакет изменений. http://oc.cs.msu.su/club/html/node2.html#SECTION00022000000000000000 Насколько я понял по этому посту , настройками wal от записи на диск по каждому коммиту не избавиться, потому что данные на диск все-таки будут записываться, но не в таблицу, а в лог.В общем да.ok MBGзаписать в лог соответствующее событие не требует каких-то трудоемких операций, это ведь не обновление данных в таблицахОбсуждался вопрос о кэшировании. Он действительно очень важен. Потому что узким местом могут оказаться не "какие-то трудоемкие операции" с CPU и памятью, а запись и чтение диска. Объемы данных (кол-во страниц), которые необходимо flush-ить в файл WAL-лога, и в файл таблицы, мне кажется, должны быть сравнимы. То есть кардинальной разницы в скорости записи WAL-лога и файла таблицы нет. MBGВ отличие от оракла, постгрес работает со своими данными через файловую системуРазве оракл не умеет работать через файловую систему? MBGлучше научиться пользоваться двухфазными транзакциямиВы имеете в виду то, что в доке называется "two-phase commit"? Уже начали филосовствовать о кластерах и репликации? :-) MBGне заморачиваться на оптимизацию низкоуровневых операций.идеально, чтобы на каждом уровне было оптимально :-) ignitorИ еще вопрос - что быстрее для операции SELECT? Составной индекс или 2 индексаЗависит от условия where. Для "a=1 and b=2" - составной, для "a=1 or b=2" - два простых. MBGСоставной ... занимает физически меньше местаможет занимать почти столько же места Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Код: plaintext 1. 2. 3. 4. 5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.07.2007, 18:26 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat MBGлучше научиться пользоваться двухфазными транзакциямиВы имеете в виду то, что в доке называется "two-phase commit"? Уже начали филосовствовать о кластерах и репликации? :-) Не философия, а насущная необходимость :-) Хотел напомнить - СУБД это в частности и многопользовательский доступ, и целостность данных. Потому сравнивать скорость записи в файл и скорость сохранения данных в СУБД особого смысла не имеет. А вот вопросов про создание эффективных и надежных приложений к сожалению не вижу. Оптимизация select-ов и insert-ов это хорошо, но серьезную систему только на этом не построить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.07.2007, 10:53 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
MBGСоставной быстрее, поскольку не требует лишних вычислений и плюс к тому занимает физически меньше места. Но с появлением bitmap index scan не стоит без нужды прибегать к составным индексам. Разве чтобы order by ускорить. Сам составными индексами перестал пользоваться с появлением bitmap индексов. Я тоже по началу отказался от составных индексов, но когда размер таблицы вырос производительность резко упала. Впрочем, при кластеризации ситуация должна измениться в лучшую сторону. Просто к кластеризации только начал подходить (размер базы - 3GB). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.07.2007, 11:38 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
MBG LeXa NalBat MBGлучше научиться пользоваться двухфазными транзакциямиВы имеете в виду то, что в доке называется "two-phase commit"? Уже начали филосовствовать о кластерах и репликации? :-)Не философия, а насущная необходимость :-)Нет, это не "насущная необходимость". Думаю, в 99% проектов можно обойтись без репликации. MBGсравнивать скорость записи в файл и скорость сохранения данных в СУБД особого смысла не имеетДа, но второе зависит, и даже может определяться первым. Кстати, я не нашел, чтобы кто-нибудь в этом топике их сравнивал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.07.2007, 12:34 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Как и обещал, первые результаты: Пока разбил 1 таблицу. Получилось 102 таблицы типа CREATE TABLE data.docblc_y1999m02 ( -- Inherited: id bigint, -- Inherited: doctype bigint, -- Inherited: sumbasecur numeric, -- Inherited: idarea bigint, -- Inherited: idbranch bigint, -- Inherited: idfund bigint, -- Inherited: vo character(2), -- Inherited: iddebacc bigint, -- Inherited: idcreacc bigint, -- Inherited: numdoc character(10), -- Inherited: docdate date, -- Inherited: docsum numeric, -- Inherited: bic_counter character(9), -- Inherited: taxid_counter character(12), -- Inherited: acc_counter character(25), -- Inherited: cacc_counter character(25), -- Inherited: dateexp date, -- Inherited: datecreate date, -- Inherited: note character(1000), -- Inherited: idexecutor bigint, CONSTRAINT docblc_y1999m02_docdate_check CHECK (docdate >= '1999-02-01'::date AND docdate < '1999-03-01'::date) ) INHERITS (docblc_) WITHOUT OIDS; ALTER TABLE data.docblc_y1999m02 OWNER TO postgres; Правил никаких не делал, т.к. писать в эти таблицы могу только я, а я знаю куда чего вливать и откуда чего удалять. На запросах типа CREATE TEMPORARY TABLE tmp_table (sum_doc numeric,charcod character(3),acc_cre character(5)) WITHOUT OIDS; insert into tmp_table(sum_doc,charcod,acc_cre) select sumbasecur,charcod,ret_pair_doc_cre(docblc.id) as acc_cre from docblc join accanl on (accanl.id=docblc.iddebacc and accsin2 in ('40911','40912','40913','42301','42601')) left join locbranch on (locbranch.id=accanl.idlocbranch) where docdate>='2007-01-01' and docdate<='2007-06-30' and sumbasecur>0; select sum(sum_doc)/1000 as sum_doc,charcod from tmp_table where acc_cre='70107' group by charcod Union select sum(docsum)/1000 as sum_doc,locbranch.charcod from docblc join accanl on (accanl.id=docblc.iddebacc and accsin2 in ('40911','40912','40913','42301','42601')) left join locbranch on (locbranch.id=accanl.idlocbranch) where docdate>='2007-01-01' and docdate<='2007-06-30' and idcreacc in (select id from accanl where accsin2='70107') group by locbranch.charcod; select * from tmp_table; при выбраном периоде 1 неделя выйгрыш по побитой таблице составил 15 раз, тот же запрос за полугодие 4 раза. Это пока так - первые впечатления. Стоит ли продолжать и смотреть в сторону кластеризации индексов? Или по сравнению с разделением это большого выйгрыша в селектах не даст? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.07.2007, 16:02 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Кластеризация может ЕЩЕ дать выигрыш в десятки раз. То есть если сейчас оптимизация в 10 раз, то будет в сотни. Но только на определенном виде запросов. Снова повторять не буду, см. подробности по ссылке http://postgrestips.blogspot.com/2007/06/cluster.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 07.07.2007, 21:59 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Наблюдение: при переименовании таблиц в хранимых процедурах их имена автоматом не переименовываются. Нужен совет. Есть у меня таблица restanl CREATE TABLE restanl ( idaccanl bigint, restanl_date date, turndeb numeric(19,2), turncre numeric(19,2), rest numeric(19,2), turndebnc numeric(19,2), turncrenc numeric(19,2), restnc numeric(19,2), datelastchange date ) WITHOUT OIDS; в ней хранятся остатки и обороты по счетам клиентов, т. о. на каждый день если счет не закрыт, в restanl есть остаток и обороты по нему. Я разделил эту таблицу по месяцам, предполагая, что запросы должны работать быстреее, если поиск идет по частям таблицы, а не по всем 10млн. записей. Однако, при первых же тестах на большой период в запросе выясилось, что запрос типа: select charcod,sum(abs(turndeb)) as td,sum(abs(turncre)) as tc from restanl_old join accanl on (restanl_old.idaccanl=accanl.id) left join fvaluedia on (fvaluedia.idrow=accanl.id and fvaluedia.idfeature=749630 and fvaluedia.fvalue not in ('Накопительный','Счет КБК') ) left join locbranch on (accanl.idlocbranch=locbranch.id) where (restanl_date >'2006-1-31' and restanl_date <='2006-07-31') and accanl.accanl_fund=56537 and ((accanl.dateclose>='2006-07-01' or accanl.dateclose is null ) and accanl.dateopen<='2006-07-31') and ((accanl.accsin1 in ('401','402','403','404','405','406','407')) or (accanl.accsin2 in ('40802','40804','40805','40806','40807'))) and idfeature is not null group by accanl.id,charcod выполняется по старой таблице --Total query runtime: 43985 ms. --2224 rows retrieved. по новой, распределенной таблице --Total query runtime: 231156 ms. --2224 rows retrieved. причем повторный запрос по обеим таблицам дает одно и то же время (видимо работает кэш) --Total query runtime: 4828 ms. --2224 rows retrieved. EXPLAIN ANALYZE по запросу со старой таблицей "GroupAggregate (cost=241769.67..243151.99 rows=42533 width=40) (actual time=43435.108..44419.309 rows=2224 loops=1)" " -> Sort (cost=241769.67..241876.00 rows=42533 width=40) (actual time=43434.668..43846.874 rows=258575 loops=1)" " Sort Key: accanl.id, locbranch.charcod" " -> Hash Join (cost=41205.24..237564.67 rows=42533 width=40) (actual time=13816.126..42273.569 rows=258575 loops=1)" " Hash Cond: (restanl_old.idaccanl = accanl.id)" " -> Bitmap Heap Scan on restanl_old (cost=32869.89..215972.52 rows=2053175 width=24) (actual time=3597.128..30812.620 rows=1824364 loops=1)" " Recheck Cond: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Bitmap Index Scan on idx13 (cost=0.00..32356.60 rows=2053175 width=0) (actual time=3576.962..3576.962 rows=1824364 loops=1)" " Index Cond: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Hash (cost=8320.36..8320.36 rows=1199 width=32) (actual time=10218.953..10218.953 rows=2224 loops=1)" " -> Hash Left Join (cost=98.06..8320.36 rows=1199 width=32) (actual time=86.268..10215.382 rows=2224 loops=1)" " Hash Cond: (accanl.idlocbranch = locbranch.id)" " -> Nested Loop (cost=85.59..8299.32 rows=1199 width=24) (actual time=86.188..10211.567 rows=2224 loops=1)" " -> Bitmap Heap Scan on accanl (cost=85.59..4951.53 rows=1342 width=16) (actual time=39.763..6831.005 rows=2251 loops=1)" " Recheck Cond: ((accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[])) OR (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[])))" " Filter: ((accanl_fund = 56537) AND ((dateclose >= '2006-07-01'::date) OR (dateclose IS NULL)) AND (dateopen <= '2006-07-31'::date))" " -> BitmapOr (cost=85.59..85.59 rows=4518 width=0) (actual time=2.349..2.349 rows=0 loops=1)" " -> Bitmap Index Scan on idx30 (cost=0.00..54.80 rows=3336 width=0) (actual time=1.598..1.598 rows=3330 loops=1)" " Index Cond: (accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[]))" " -> Bitmap Index Scan on idx31 (cost=0.00..30.11 rows=1181 width=0) (actual time=0.747..0.747 rows=1116 loops=1)" " Index Cond: (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[]))" " -> Index Scan using idx_dia_1 on fvaluedia (cost=0.00..2.48 rows=1 width=8) (actual time=1.221..1.498 rows=1 loops=2251)" " Index Cond: (fvaluedia.idrow = accanl.id)" " Filter: ((idfeature = 749630) AND ((fvalue)::text <> ALL (('{Накопительный,"Счет КБК"}'::character varying[])::text[])) AND (idfeature IS NOT NULL))" " -> Hash (cost=11.10..11.10 rows=110 width=24) (actual time=0.054..0.054 rows=6 loops=1)" " -> Seq Scan on locbranch (cost=0.00..11.10 rows=110 width=24) (actual time=0.037..0.041 rows=6 loops=1)" "Total runtime: 44429.273 ms" тоже с новой "GroupAggregate (cost=42118.93..43344.27 rows=37703 width=60) (actual time=217102.431..217933.799 rows=2224 loops=1)" " -> Sort (cost=42118.93..42213.18 rows=37703 width=60) (actual time=217101.956..217351.461 rows=258575 loops=1)" " Sort Key: accanl.id, locbranch.charcod" " -> Nested Loop (cost=98.06..38148.05 rows=37703 width=60) (actual time=257.351..215724.877 rows=258575 loops=1)" " Join Filter: (public.restanl.idaccanl = accanl.id)" " -> Nested Loop (cost=98.06..8859.36 rows=1199 width=32) (actual time=3.238..148.988 rows=2224 loops=1)" " -> Hash Left Join (cost=98.06..4973.59 rows=1342 width=24) (actual time=3.147..71.506 rows=2251 loops=1)" " Hash Cond: (accanl.idlocbranch = locbranch.id)" " -> Bitmap Heap Scan on accanl (cost=85.59..4951.53 rows=1342 width=16) (actual time=3.092..64.353 rows=2251 loops=1)" " Recheck Cond: ((accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[])) OR (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[])))" " Filter: ((accanl_fund = 56537) AND ((dateclose >= '2006-07-01'::date) OR (dateclose IS NULL)) AND (dateopen <= '2006-07-31'::date))" " -> BitmapOr (cost=85.59..85.59 rows=4518 width=0) (actual time=2.146..2.146 rows=0 loops=1)" " -> Bitmap Index Scan on idx30 (cost=0.00..54.80 rows=3336 width=0) (actual time=1.539..1.539 rows=3330 loops=1)" " Index Cond: (accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[]))" " -> Bitmap Index Scan on idx31 (cost=0.00..30.11 rows=1181 width=0) (actual time=0.603..0.603 rows=1116 loops=1)" " Index Cond: (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[]))" " -> Hash (cost=11.10..11.10 rows=110 width=24) (actual time=0.036..0.036 rows=6 loops=1)" " -> Seq Scan on locbranch (cost=0.00..11.10 rows=110 width=24) (actual time=0.021..0.025 rows=6 loops=1)" " -> Index Scan using idx_dia_1 on fvaluedia (cost=0.00..2.88 rows=1 width=8) (actual time=0.024..0.030 rows=1 loops=2251)" " Index Cond: (fvaluedia.idrow = accanl.id)" " Filter: ((idfeature = 749630) AND ((fvalue)::text <> ALL (('{Накопительный,"Счет КБК"}'::character varying[])::text[])) AND (idfeature IS NOT NULL))" " -> Append (cost=0.00..24.33 rows=8 width=44) (actual time=15.042..96.799 rows=116 loops=2224)" " -> Index Scan using rstanl_idx1 on restanl (cost=0.00..1.28 rows=1 width=44) (actual time=0.011..0.011 rows=0 loops=2224)" " Index Cond: ((public.restanl.idaccanl = accanl.id) AND (fvaluedia.idrow = public.restanl.idaccanl))" " Filter: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Index Scan using rstanl_y2006m01_idx2 on rstanl_y2006m01 restanl (cost=0.00..3.17 rows=1 width=24) (actual time=12.406..12.406 rows=0 loops=2224)" " Index Cond: ((data.restanl.idaccanl = accanl.id) AND (fvaluedia.idrow = data.restanl.idaccanl))" " Filter: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Index Scan using rstanl_y2006m02_idx2 on rstanl_y2006m02 restanl (cost=0.00..3.25 rows=1 width=24) (actual time=2.007..14.875 rows=17 loops=2224)" " Index Cond: ((data.restanl.idaccanl = accanl.id) AND (fvaluedia.idrow = data.restanl.idaccanl))" " Filter: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Index Scan using rstanl_y2006m03_idx2 on rstanl_y2006m03 restanl (cost=0.00..3.32 rows=1 width=24) (actual time=2.198..14.314 rows=20 loops=2224)" " Index Cond: ((data.restanl.idaccanl = accanl.id) AND (fvaluedia.idrow = data.restanl.idaccanl))" " Filter: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Index Scan using rstanl_y2006m04_idx2 on rstanl_y2006m04 restanl (cost=0.00..3.28 rows=1 width=24) (actual time=1.837..13.475 rows=19 loops=2224)" " Index Cond: ((data.restanl.idaccanl = accanl.id) AND (fvaluedia.idrow = data.restanl.idaccanl))" " Filter: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Index Scan using rstanl_y2006m05_idx2 on rstanl_y2006m05 restanl (cost=0.00..3.32 rows=1 width=24) (actual time=2.601..13.485 rows=20 loops=2224)" " Index Cond: ((data.restanl.idaccanl = accanl.id) AND (fvaluedia.idrow = data.restanl.idaccanl))" " Filter: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Index Scan using rstanl_y2006m06_idx2 on rstanl_y2006m06 restanl (cost=0.00..3.34 rows=1 width=24) (actual time=2.218..12.811 rows=21 loops=2224)" " Index Cond: ((data.restanl.idaccanl = accanl.id) AND (fvaluedia.idrow = data.restanl.idaccanl))" " Filter: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Index Scan using rstanl_y2006m07_idx2 on rstanl_y2006m07 restanl (cost=0.00..3.36 rows=1 width=24) (actual time=2.517..15.324 rows=21 loops=2224)" " Index Cond: ((data.restanl.idaccanl = accanl.id) AND (fvaluedia.idrow = data.restanl.idaccanl))" " Filter: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" "Total runtime: 217937.207 ms" есть у меня подозрение, что я либо 1) слишком мелко поделил таблицу (возможно имеет смысл поделить ее по годам, если принять во внимание то, что запросы на стыке лет бывают редко) 2) поделил таблицу не по тому полю (большинство связей в запросах используют idaccanl, но всегда имеется условие либо период, либо на дату) 3) запрос никуда не годится, либо для новой таблицы его нужно переписать - но как? подскажите, что делать - может вернуть все обратно для этой таблицы? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 13:09 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
constraint_exclusion = on ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 13:45 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
show constraint_exclusion on ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 13:59 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Хотя вроде включен, но вообще странно, . Запрос написан ужасно - настолько запутанная конструкция не поддается никакой отладке. Попробуйте сделать пошаговую обработку данных, как минимум, станет ясно, где узкое место, а возможно, сразу будет работать быстрее http://postgrestips.blogspot.com/2007/07/temp.html P.S. Для указанного типа запроса и объема данных время выполнения 43985 ms просто огромное, пора создавать функционалы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 14:08 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Думаю, что запрос по исходной таблицы работает быстрее только за счет кэша. А разделение по месяцам здесь вполне нормально, разделять нужно именно по условию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 14:18 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Ужасный запрос - это следствие ужасной структуры данных в Diasoft Bank4х4. Большинство признаков объектов у них - являются прицепленными классификаторами и хранятся в разных таблицах, причем классификатором может быть конкретное значение или его отсутствие. Обновлять данные приходится минимум 2 раза в день. Поэтому самый быстрый способ без всякой логики заливать данные в таблицы-аналоги, а потом пытаться связать все вместе. Вьюхи я пробовал - быстродействия они , в моем случае, не прибавляли. Но я готов попробовать упростить этот конкретный запрос. О результатах сообщу. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 14:21 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Есть такое подозрение, что медленно запрос выполняется из-за группировки - часть данных отсеивается не до, а после выполнения группировки. Но точно сказать не могу, поскольку не понимаю логику обработки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 14:42 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Чудеса - сделал две вьюхи CREATE OR REPLACE VIEW data.t_acc_charcod AS SELECT accanl.id AS idaccanl, locbranch.charcod FROM accanl LEFT JOIN locbranch ON accanl.idlocbranch = locbranch.id WHERE accanl.accanl_fund = 56537 AND (accanl.dateclose >= '2006-07-01'::date OR accanl.dateclose IS NULL) AND accanl.dateopen <= '2006-07-31'::date AND ((accanl.accsin1 = ANY (ARRAY['401'::bpchar, '402'::bpchar, '403'::bpchar, '404'::bpchar, '405'::bpchar, '406'::bpchar, '407'::bpchar])) OR (accanl.accsin2 = ANY (ARRAY['40802'::bpchar, '40804'::bpchar, '40805'::bpchar, '40806'::bpchar, '40807'::bpchar]))); ALTER TABLE data.t_acc_charcod OWNER TO postgres; и CREATE OR REPLACE VIEW data.t_fvalue AS SELECT fvaluedia.idrow FROM fvaluedia WHERE fvaluedia.idfeature = 749630 AND (fvaluedia.fvalue::text <> ALL (ARRAY['Накопительный'::character varying, 'Счет КБК'::character varying]::text[])); ALTER TABLE data.t_fvalue OWNER TO postgres; результаты поразительные /* select data.t_acc_charcod.idaccanl,restanl.turndebnc,restanl.turncrenc from data.t_acc_charcod left join data.t_fvalue on data.t_fvalue.idrow=data.t_acc_charcod.idaccanl join restanl on restanl.idaccanl=data.t_acc_charcod.idaccanl where (restanl_date >'2006-1-31' and restanl_date <='2006-07-31') */ --Total query runtime: 38797 ms. --260805 rows retrieved. /* select data.t_acc_charcod.idaccanl,restanl_new.turndebnc,restanl_new.turncrenc from data.t_acc_charcod left join data.t_fvalue on data.t_fvalue.idrow=data.t_acc_charcod.idaccanl join restanl_new on restanl_new.idaccanl=data.t_acc_charcod.idaccanl where (restanl_date >'2006-1-31' and restanl_date <='2006-07-31') */ --Total query runtime: 2812 ms. --260805 rows retrieved. explain analyze: "Hash Join (cost=8878.42..74507.48 rows=42216 width=44) (actual time=96.485..4507.101 rows=260805 loops=1)" " Hash Cond: (public.restanl_new.idaccanl = accanl.id)" " -> Append (cost=2.28..51526.42 rows=1824368 width=44) (actual time=0.185..3234.344 rows=1824364 loops=1)" " -> Bitmap Heap Scan on restanl_new (cost=2.28..6.68 rows=3 width=44) (actual time=0.060..0.060 rows=0 loops=1)" " Recheck Cond: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Bitmap Index Scan on rstanl_idx2 (cost=0.00..2.28 rows=3 width=0) (actual time=0.056..0.056 rows=0 loops=1)" " Index Cond: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Index Scan using rstanl_y2006m01_idx1 on rstanl_y2006m01 restanl_new (cost=0.00..4.28 rows=1 width=24) (actual time=0.089..0.089 rows=0 loops=1)" " Index Cond: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Seq Scan on rstanl_y2006m02 restanl_new (cost=0.00..7403.40 rows=262093 width=24) (actual time=0.033..275.149 rows=262093 loops=1)" " Filter: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Seq Scan on rstanl_y2006m03 restanl_new (cost=0.00..8665.17 rows=306811 width=24) (actual time=0.054..325.326 rows=306811 loops=1)" " Filter: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Seq Scan on rstanl_y2006m04 restanl_new (cost=0.00..8013.92 rows=283661 width=24) (actual time=0.053..303.852 rows=283661 loops=1)" " Filter: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Seq Scan on rstanl_y2006m05 restanl_new (cost=0.00..8767.59 rows=310506 width=24) (actual time=0.054..326.227 rows=310506 loops=1)" " Filter: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Seq Scan on rstanl_y2006m06 restanl_new (cost=0.00..9129.40 rows=323293 width=24) (actual time=0.056..338.307 rows=323293 loops=1)" " Filter: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Seq Scan on rstanl_y2006m07 restanl_new (cost=0.00..9536.00 rows=338000 width=24) (actual time=0.053..352.677 rows=338000 loops=1)" " Filter: ((restanl_date > '2006-01-31'::date) AND (restanl_date <= '2006-07-31'::date))" " -> Hash (cost=8859.36..8859.36 rows=1342 width=8) (actual time=96.222..96.222 rows=2251 loops=1)" " -> Hash Left Join (cost=98.06..8859.36 rows=1342 width=8) (actual time=3.419..93.725 rows=2251 loops=1)" " Hash Cond: (accanl.idlocbranch = locbranch.id)" " -> Nested Loop Left Join (cost=85.59..8837.31 rows=1342 width=16) (actual time=3.367..90.748 rows=2251 loops=1)" " -> Bitmap Heap Scan on accanl (cost=85.59..4951.53 rows=1342 width=16) (actual time=3.204..50.242 rows=2251 loops=1)" " Recheck Cond: ((accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[])) OR (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[])))" " Filter: ((accanl_fund = 56537) AND ((dateclose >= '2006-07-01'::date) OR (dateclose IS NULL)) AND (dateopen <= '2006-07-31'::date))" " -> BitmapOr (cost=85.59..85.59 rows=4518 width=0) (actual time=2.257..2.257 rows=0 loops=1)" " -> Bitmap Index Scan on idx30 (cost=0.00..54.80 rows=3336 width=0) (actual time=1.590..1.590 rows=3330 loops=1)" " Index Cond: (accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[]))" " -> Bitmap Index Scan on idx31 (cost=0.00..30.11 rows=1181 width=0) (actual time=0.664..0.664 rows=1116 loops=1)" " Index Cond: (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[]))" " -> Index Scan using idx_dia_1 on fvaluedia (cost=0.00..2.88 rows=1 width=8) (actual time=0.013..0.015 rows=1 loops=2251)" " Index Cond: (fvaluedia.idrow = accanl.id)" " Filter: ((idfeature = 749630) AND ((fvalue)::text <> ALL (('{Накопительный,"Счет КБК"}'::character varying[])::text[])))" " -> Hash (cost=11.10..11.10 rows=110 width=8) (actual time=0.035..0.035 rows=6 loops=1)" " -> Seq Scan on locbranch (cost=0.00..11.10 rows=110 width=8) (actual time=0.021..0.025 rows=6 loops=1)" "Total runtime: 4607.482 ms" Будут комментарии? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 14:49 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Вообщето по explain видно что до вьюх набор из 7 месяцев поднимался с диска 2224 раза, а в последнем варианте только 1 раз. Видимо в этом дело - поправьте меня, если вру. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 14:54 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
При использовании группировок планировщик запроса часто себя ведет, скажем так, неадекватно. Потому лучше итерационный подход - планировщик по отдельности оптимизирует выполнение каждого запроса и дело в шляпе. И запросы простые и работают быстро. P.S. Кстати, при использовании функционалов подобный анализ проводится за десятки миллисекунд :-) На машине целерон 2,4 ГГц, ОЗУ 256 Мб, таблица 5 миллионов записей. На вашем железе можно терабайтные базы гонять. P.P.S. Продолжать будем? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 15:08 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Пожалуй нет, только вопрос параметризовать вьюхи я так понимаю нельзя? Стало быть мне нужно использовать во вьюхах хранимые процедуры и переписывать запросы? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 15:11 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Только не это!!! Нужно из хранимых процедур создавать виды с нужными параметрами, но ни в коем случае нельзя в видах использовать хранимки. Это особенность постгреса, на которой часто спотыкаются ораклисты. Именно потому я и говорил о временных видах - запустил процедуру с нужными параметрами, она создала временные виды с этими параметрами, потом из видов берем данные, а после завершения транзакции или сессии виды автоматически удаляются. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 15:21 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
То есть, примерно то же самое, что я делаю сейчас при помощи CREATE TEMP TABLE TMP_TABLE ...; SELECT ... FROM TMP_TABLE ...; DROP TABLE TMP_TABLE; А какая принципиальная разница между временными таблицами и видами? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 15:29 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Ага. Только вот это не нужно: DROP TABLE TMP_TABLE; Практически важная разница между временными таблицами и видами указана в статье по ссылочке выше: "В большинстве случаев следует использовать временные виды, если сомневаетесь, создавайте именно их. Временные таблицы полезны тогда, когда небольшая, но ресурсоемкая выборка используется многократно." Ну а принципиально разница такая же, как между обычными таблицами и видами. Если что не понятно, спрашивайте, дополню статью. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 15:42 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Попробую вникнуть самостоятельно. Большое спасибо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 15:58 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Решил сделать так 1. Создать хранимые процедуры на более общие моменты, типа "ID и код филиала счетов клиентов по валюте, существовавшие в период с ... по, в счетах I порядка [ или II порядка]" CREATE OR REPLACE FUNCTION data.new_tmpview_acc_charcod(idfund bigint, date_b bpchar, date_e bpchar, accsin1 bpchar, accsin2 bpchar, name_new_tmpview bpchar) RETURNS character AS $BODY$select 'CREATE OR REPLACE TEMP VIEW '||$6||' AS SELECT accanl.id AS idaccanl, locbranch.charcod FROM accanl LEFT JOIN locbranch ON accanl.idlocbranch = locbranch.id WHERE accanl.accanl_fund = '||$1||' AND (accanl.dateclose >= '''||$2||'''::date OR accanl.dateclose IS NULL) AND accanl.dateopen <= '''||$3||'''::date AND ((accanl.accsin1 = ANY (''{'||$4||'}''::bpchar[]))'||CASE WHEN char_length($5)=0 THEN '' ELSE ' OR (accanl.accsin2 = ANY (''{'||$5||'}''::bpchar[]))' END||'); ALTER TABLE '||$6||' OWNER TO postgres;'$BODY$ LANGUAGE 'sql' VOLATILE; большинство ограничений в запросах описываются этой формулой 2. Затем в коде VB(VBA) получаю по нужным мне параметрам строку с запросом на создание нужной мне вьюхи: 'создаются временные VIEW rs.Open "select data.new_tmpview_acc_charcod(56537, " & date_beg & ", " & date_end & ", '401,402,403,404,405,406,407', '40802,40804,40805,40806,40807', 'acc_id_char') as strsql;", cn strsql = rs!strsql rs.Close rs.Open "select data.new_tmp_view_fvalue_id_and_cond(749630,'and fvaluedia.fvalue not in (''Накопительный'',''Счет КБК'')','tmp_fvalue') as strsql;" strsql = strsql & rs!strsql rs.Close rs.Open strsql, cn ' теперь они есть, используем strsql = "select acc_id_char.charcod,sum(abs(turndebnc)) as td,sum(abs(turncrenc)) as tc from restanl join " _ & "acc_id_char on (restanl.idaccanl=acc_id_char.idaccanl) left join tmp_fvalue on (tmp_fvalue.idrow=acc_id_char.idaccanl) " _ & " where (restanl_date >=" & date_beg_hyb & " and restanl_date <=" & date_end & ") group by acc_id_char.idaccanl,acc_id_char.charcod" rs.Open strsql, cn, adOpenForwardOnly, adLockReadOnly Надо будет конечно много чего переделать, но зато на будущее большинство вопросов снимется. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 08.07.2007, 20:04 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Еще одна неприятность - раньше простой и быстрый запрос: select restanl_date from restanl where restanl_date<='2007-07-01' order by restanl_date desc limit 1 теперь выполняется жутко долго, пробовал ограничить снизу месяцем: select restanl_date from restanl where restanl_date>'2007-06-01' and restanl_date<='2007-07-01' order by restanl_date desc limit 1 но и тут как-то не блестяще: Limit (cost=66764.25..66764.25 rows=1 width=4) -> Sort (cost=66764.25..67886.39 rows=448857 width=4) Sort Key: public.restanl.restanl_date -> Result (cost=2.28..13665.79 rows=448857 width=4) -> Append (cost=2.28..13665.79 rows=448857 width=4) -> Bitmap Heap Scan on restanl (cost=2.28..6.68 rows=3 width=4) Recheck Cond: ((restanl_date > '2007-06-01'::date) AND (restanl_date <= '2007-07-01'::date)) -> Bitmap Index Scan on rstanl_idx2 (cost=0.00..2.28 rows=3 width=0) Index Cond: ((restanl_date > '2007-06-01'::date) AND (restanl_date <= '2007-07-01'::date)) -> Seq Scan on rstanl_y2007m06 restanl (cost=0.00..13188.21 rows=448477 width=4) Filter: ((restanl_date > '2007-06-01'::date) AND (restanl_date <= '2007-07-01'::date)) -> Bitmap Heap Scan on rstanl_y2007m07 restanl (cost=8.12..470.90 rows=377 width=4) Recheck Cond: ((restanl_date > '2007-06-01'::date) AND (restanl_date <= '2007-07-01'::date)) -> Bitmap Index Scan on rstanl_y2007m07_idx1 (cost=0.00..8.02 rows=377 width=0) Index Cond: ((restanl_date > '2007-06-01'::date) AND (restanl_date <= '2007-07-01'::date)) Проверять на точную дату не могу, остатки есть не за каждый день. Решение в общем-то есть - собрать в табличку существующие дни и искать в них, но может есть решение посимпатичнее? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 09:49 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
ignitorСтоит ли продолжать и смотреть в сторону кластеризации индексов? http://postgrestips.blogspot.com/2007/06/cluster.html... применяется операция кластеризации (cluster) таблиц по указанному индексу, которая упорядочивает индексы ... http://www.postgresql.org/docs/8.2/static/sql-cluster.htmlcluster a table according to an indexКластеризуется таблица, а не индекс. ignitorвыполняется по старой таблице --Total query runtime: 43985 ms. --2224 rows retrieved. по новой, распределенной таблице --Total query runtime: 231156 ms. --2224 rows retrieved. причем повторный запрос по обеим таблицам дает одно и то же время (видимо работает кэш) --Total query runtime: 4828 ms. --2224 rows retrieved. ignitorEXPLAIN ANALYZE по запросу со старой таблицей -> Bitmap Heap Scan on accanl (cost=85.59..4951.53 rows=1342 width=16) (actual time=39.763..6831.005 rows=2251 loops=1) Recheck Cond: ((accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[])) OR (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[]))) Filter: ((accanl_fund = 56537) AND ((dateclose >= '2006-07-01'::date) OR (dateclose IS NULL)) AND (dateopen <= '2006-07-31'::date)) -> BitmapOr (cost=85.59..85.59 rows=4518 width=0) (actual time=2.349..2.349 rows=0 loops=1) -> Bitmap Index Scan on idx30 (cost=0.00..54.80 rows=3336 width=0) (actual time=1.598..1.598 rows=3330 loops=1) Index Cond: (accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[])) -> Bitmap Index Scan on idx31 (cost=0.00..30.11 rows=1181 width=0) (actual time=0.747..0.747 rows=1116 loops=1) Index Cond: (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[])) -> Index Scan using idx_dia_1 on fvaluedia (cost=0.00..2.48 rows=1 width=8) (actual time=1.221..1.498 rows=1 loops=2251) Index Cond: (fvaluedia.idrow = accanl.id) Filter: ((idfeature = 749630) AND ((fvalue)::text <> ALL (('{Накопительный,"Счет КБК"}'::character varying[])::text[])) AND (idfeature IS NOT NULL)) тоже с новой -> Bitmap Heap Scan on accanl (cost=85.59..4951.53 rows=1342 width=16) (actual time=3.092..64.353 rows=2251 loops=1) Recheck Cond: ((accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[])) OR (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[]))) Filter: ((accanl_fund = 56537) AND ((dateclose >= '2006-07-01'::date) OR (dateclose IS NULL)) AND (dateopen <= '2006-07-31'::date)) -> BitmapOr (cost=85.59..85.59 rows=4518 width=0) (actual time=2.146..2.146 rows=0 loops=1) -> Bitmap Index Scan on idx30 (cost=0.00..54.80 rows=3336 width=0) (actual time=1.539..1.539 rows=3330 loops=1) Index Cond: (accsin1 = ANY ('{401,402,403,404,405,406,407}'::bpchar[])) -> Bitmap Index Scan on idx31 (cost=0.00..30.11 rows=1181 width=0) (actual time=0.603..0.603 rows=1116 loops=1) Index Cond: (accsin2 = ANY ('{40802,40804,40805,40806,40807}'::bpchar[])) -> Index Scan using idx_dia_1 on fvaluedia (cost=0.00..2.88 rows=1 width=8) (actual time=0.024..0.030 rows=1 loops=2251) Index Cond: (fvaluedia.idrow = accanl.id) Filter: ((idfeature = 749630) AND ((fvalue)::text <> ALL (('{Накопительный,"Счет КБК"}'::character varying[])::text[])) AND (idfeature IS NOT NULL))В этом сравнительном тесте вы допустили ошибку. Видимо "кэш сработал" не только при повторных запросах к обоим таблицам, но и например при запросе к новой таблице. Обратите внимание, что одинаковые части запроса выполняются на несколько порядков разное время: "Bitmap Heap Scan on accanl" 6831.005 против 64.353, и "Index Scan using idx_dia_1 on fvaluedia" 1.498 против 0.030. Для корректного тестирования надо смотреть время выполнения второго подряд запроса (данные уже загружены в кэш), либо "шаманством" очищать кэш. ignitorЧудеса - сделал две вьюхи результаты поразительные --Total query runtime: 38797 ms. --260805 rows retrieved. --Total query runtime: 2812 ms. --260805 rows retrieved. Вообщето по explain видно что до вьюх набор из 7 месяцев поднимался с диска 2224 раза, а в последнем варианте только 1 раз.Ничего не видно. :-) Что вы сравниваете? А: запрос с "group by", возвращающий 2224 строки, при котором "набор из 7 месяцев поднимался с диска 2224 раза" с Б: запросом с view, который без "group by", и возвращает 260805 строк? Нет уж, давайте сравнивать планы выполнения запросов, возвращающих одинаковые результаты. Для этого приведите пожалуйста план выполнения аналогичного запроса без view, к которому относится ваш комментарий "Total query runtime: 38797 ms. 260805 rows retrieved". MBGПри использовании группировок планировщик запроса часто себя ведет, скажем так, неадекватно. http://www.redivi.com/~bob/oscon2005_pgsql_pdf/OSCON_Explaining_Explain_Public.pdfYou are not smarter than the planner (where you != Tom):-) MBGПотому лучше итерационный подход - планировщик по отдельности оптимизирует выполнение каждого запроса и дело в шляпе. И запросы простые и работают быстро.Объясните пожалуйста подробнее этот "итерационный подход", если можно с примером. ignitorЕще одна неприятность - раньше простой и быстрый запрос: select restanl_date from restanl where restanl_date<='2007-07-01' order by restanl_date desc limit 1 теперь выполняется жутко долгоИнтересная проблема. Пока не могу придумать, как ее решить. :-( Разработчики оптимизировали запросы "order by limit", но не для партиционных таблиц с учетом условий check. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 12:32 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat http://postgrestips.blogspot.com/2007/06/cluster.html... применяется операция кластеризации (cluster) таблиц по указанному индексу, которая упорядочивает индексы ... http://www.postgresql.org/docs/8.2/static/sql-cluster.htmlcluster a table according to an indexКластеризуется таблица, а не индекс. Где-то в доках видел, что и файл индекса упорядочивается. LeXa NalBat MBGПотому лучше итерационный подход - планировщик по отдельности оптимизирует выполнение каждого запроса и дело в шляпе. И запросы простые и работают быстро.Объясните пожалуйста подробнее этот "итерационный подход", если можно с примером. Примеры были по ссылке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 12:50 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
MBG LeXa NalBatКластеризуется таблица, а не индекс.Где-то в доках видел, что и файл индекса упорядочивается.сомневаюсь MBG LeXa NalBat MBGПотому лучше итерационный подход - планировщик по отдельности оптимизирует выполнение каждого запроса и дело в шляпе. И запросы простые и работают быстро.Объясните пожалуйста подробнее этот "итерационный подход", если можно с примером.Примеры были по ссылке.Нету ссылки в вашем посте . :-O ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 13:04 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Очень грустно explain analyse select restanl_date as MaxRest from restanl where restanl_date>'2007-06-09' order by restanl_date desc limit 1 "Limit (cost=108264.63..108264.63 rows=1 width=4) (actual time=1826.053..1826.054 rows=1 loops=1)" " -> Sort (cost=108264.63..109945.94 rows=672525 width=4) (actual time=1826.043..1826.043 rows=1 loops=1)" " Sort Key: public.restanl.restanl_date" " -> Result (cost=76.13..26746.81 rows=672525 width=4) (actual time=0.362..1126.831 rows=412764 loops=1)" " -> Append (cost=76.13..26746.81 rows=672525 width=4) (actual time=0.360..802.623 rows=412764 loops=1)" " -> Bitmap Heap Scan on restanl (cost=76.13..369.56 rows=4114 width=4) (actual time=0.154..0.154 rows=0 loops=1)" " Recheck Cond: (restanl_date > '2007-06-09'::date)" " -> Bitmap Index Scan on rstanl_idx2 (cost=0.00..75.11 rows=4114 width=0) (actual time=0.147..0.147 rows=0 loops=1)" " Index Cond: (restanl_date > '2007-06-09'::date)" " -> Index Scan using rstanl_y2007m06_idx1 on rstanl_y2007m06 restanl (cost=0.00..22610.03 rows=611870 width=4) (actual time=0.204..381.522 rows=318490 loops=1)" " Index Cond: (restanl_date > '2007-06-09'::date)" " -> Bitmap Heap Scan on rstanl_y2007m07 restanl (cost=798.45..3767.22 rows=56541 width=4) (actual time=59.320..129.933 rows=94274 loops=1)" " Recheck Cond: (restanl_date > '2007-06-09'::date)" " -> Bitmap Index Scan on rstanl_y2007m07_idx1 (cost=0.00..784.32 rows=56541 width=0) (actual time=39.765..39.765 rows=169637 loops=1)" " Index Cond: (restanl_date > '2007-06-09'::date)" "Total runtime: 1827.946 ms" Грустно explain analyse select Max(restanl_date) as MaxRest from restanl where restanl_date>'2007-06-09' "Aggregate (cost=28428.12..28428.13 rows=1 width=4) (actual time=905.358..905.359 rows=1 loops=1)" " -> Append (cost=76.13..26746.81 rows=672525 width=4) (actual time=0.222..731.128 rows=412764 loops=1)" " -> Bitmap Heap Scan on restanl (cost=76.13..369.56 rows=4114 width=4) (actual time=0.106..0.106 rows=0 loops=1)" " Recheck Cond: (restanl_date > '2007-06-09'::date)" " -> Bitmap Index Scan on rstanl_idx2 (cost=0.00..75.11 rows=4114 width=0) (actual time=0.101..0.101 rows=0 loops=1)" " Index Cond: (restanl_date > '2007-06-09'::date)" " -> Index Scan using rstanl_y2007m06_idx1 on rstanl_y2007m06 restanl (cost=0.00..22610.03 rows=611870 width=4) (actual time=0.114..318.987 rows=318490 loops=1)" " Index Cond: (restanl_date > '2007-06-09'::date)" " -> Bitmap Heap Scan on rstanl_y2007m07 restanl (cost=798.45..3767.22 rows=56541 width=4) (actual time=56.449..125.029 rows=94274 loops=1)" " Recheck Cond: (restanl_date > '2007-06-09'::date)" " -> Bitmap Index Scan on rstanl_y2007m07_idx1 (cost=0.00..784.32 rows=56541 width=0) (actual time=38.239..38.239 rows=169637 loops=1)" " Index Cond: (restanl_date > '2007-06-09'::date)" "Total runtime: 905.580 ms" Ностальгия explain analyse select restanl_date as MaxRest from restanl_old where restanl_date>'2007-06-09' order by restanl_date desc limit 1 "Limit (cost=0.00..0.98 rows=1 width=4) (actual time=146.714..146.715 rows=1 loops=1)" " -> Index Scan Backward using idx13 on restanl_old (cost=0.00..367432.40 rows=374515 width=4) (actual time=146.710..146.710 rows=1 loops=1)" " Index Cond: (restanl_date > '2007-06-09'::date)" "Total runtime: 146.774 ms" ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 13:41 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat MBG LeXa NalBatКластеризуется таблица, а не индекс.Где-то в доках видел, что и файл индекса упорядочивается.сомневаюсь Возможно, что там немного замудренный английский и в глаза это не бросается. Но это легко проверить: 1. CREATE INDEX out_object_id_idx ON out USING btree (object_id); # md5sum 283800 02935d31392e749e166538a4639c9593 283800 2. cluster out_object_id_idx on out; # md5sum 283800 md5sum: 283800: No such file or directory # md5sum 283806 815f44f75474ebee39b8f4ff7308a693 283806 3. drop index out_object_id_idx; # md5sum 283806 md5sum: 283806: No such file or directory Как говорится, без комментариев :-) LeXa NalBat MBG LeXa NalBat MBGПотому лучше итерационный подход - планировщик по отдельности оптимизирует выполнение каждого запроса и дело в шляпе. И запросы простые и работают быстро.Объясните пожалуйста подробнее этот "итерационный подход", если можно с примером.Примеры были по ссылке.Нету ссылки в вашем посте . :-O http://postgrestips.blogspot.com/2007/07/temp.html ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 13:56 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
"During the cluster operation, a temporary copy of the table is created that contains the table data in the index order. Temporary copies of each index on the table are created as well. Therefore, you need free space on disk at least equal to the sum of the table size and the index sizes. " Думаю, вопрос с перестройкой индекса закрыт. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 14:00 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
MBGВозможно, что там немного замудренный английский и в глаза это не бросается. "During the cluster operation, a temporary copy of the table is created that contains the table data in the index order. Temporary copies of each index on the table are created as well. Therefore, you need free space on disk at least equal to the sum of the table size and the index sizes."О, великий и "замудренный" английский язык. :-) Можете перевести цитату, которую вы привели... Индексы перестраиваются, но не кластеризуются (как написал ignitor) и не упорядочиваются (как написали вы в своей статье). PS: не закрывайте вопросы раньше времени :-) MBG LeXa NalBat MBGПотому лучше итерационный подход - планировщик по отдельности оптимизирует выполнение каждого запроса и дело в шляпе. И запросы простые и работают быстро.Объясните пожалуйста подробнее этот "итерационный подход", если можно с примером.Примеры были по ссылке. http://postgrestips.blogspot.com/2007/07/temp.html Вы имеете в виду "пример использования временных объектов для построения отчета (выдернул из функции на pltcl)"? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 15:23 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat MBGВозможно, что там немного замудренный английский и в глаза это не бросается. "During the cluster operation, a temporary copy of the table is created that contains the table data in the index order. Temporary copies of each index on the table are created as well. Therefore, you need free space on disk at least equal to the sum of the table size and the index sizes."О, великий и "замудренный" английский язык. :-) Можете перевести цитату, которую вы привели... Индексы перестраиваются, но не кластеризуются (как написал ignitor) и не упорядочиваются (как написали вы в своей статье). PS: не закрывайте вопросы раньше времени :-) Если индексы строятся упорядоченно и по кластеризованным данным, вы считаете, что они не кластеризованы? В цитате перечислены необходимые и достаточные условия кластеризованности индекса в строгом смысле (т.е. и сами данные тоже кластеризованы). LeXa NalBatВы имеете в виду "пример использования временных объектов для построения отчета (выдернул из функции на pltcl)"? Ага. Вместе с комментариями. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 16:39 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Подразумеваю, что индексы кластеризованы по значениям данных, поскольку если функциональный индекс задается немонотонной функцией более ничего сказать нельзя. Ну а в простейшем случае и так все очевидно... Но нам и выборка требуется набора данных, а не набора индексов, так что абсолютно бесполезно было бы кластеризовать индекс по его собственным значениям - это привело бы к неоправданным затратам при построении итоговой выборки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 16:46 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
MBGПодразумеваю, что индексы кластеризованы по значениям данных, поскольку если функциональный индекс задается немонотонной функцией более ничего сказать нельзя. Ну а в простейшем случае и так все очевидно... Но нам и выборка требуется набора данных, а не набора индексов, так что абсолютно бесполезно было бы кластеризовать индекс по его собственным значениям - это привело бы к неоправданным затратам при построении итоговой выборки. Бррр. Я бы не стал относить термин "кластер" к хранению индекса. ИМХО это неверно по сути своей. Таблица может быть упорядачена по индексу, в таком случае индекс называется кластерным, а таблица кластеризированной. Но хранится он все равно в виде бинарного дерева со ссылками на страницы, в которых возможно есть данные. Скорее всего при перестроении произойдет перебалансиорвка дерева и индекс станет более аптимальным. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 17:06 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Для начала переведу для вас. "Temporary copies of each index on the table are created as well." "Также создаются временные копии всех индексов таблицы." Перечитаем еще раз вместе "СОЗДАЮТСЯ КОПИИ ИНДЕКСОВ". И все, более ничего не написано касательно индексов. MBGЕсли индексы строятся упорядоченно и по кластеризованным данным, вы считаете, что они не кластеризованы?Не могу ответить на ваш вопрос, потому что не знаю, что такое "кластеризованный индекс". В постгресе обычно индексы это B-деревья. Я не вижу разницы, строить их "упорядоченно", или нет, все равно получится B-дерево. Как его можно кластеризовать? Не понимаю. MBGВ цитате перечислены необходимые и достаточные условия кластеризованности индекса в строгом смысле (т.е. и сами данные тоже кластеризованы).В цитате "в строгом смысле" лишь написано "СОЗДАЮТСЯ КОПИИ ИНДЕКСОВ". Какие-либо необходимые и достаточные условия неопределенного понятия "кластеризованность индекса" в ней отсутствуют. MBGПодразумеваю, что индексы кластеризованы по значениям данных... <В этом> случае и так все очевидно... Но нам и выборка требуется набора данных, а не набора индексов, так что абсолютно бесполезно было бы кластеризовать индекс по его собственным значениям - это привело бы к неоправданным затратам при построении итоговой выборки.Что такое "блабуда"? Это слово я только что придумал из "bla-bla-bla" и "лабуда". А вот что такое "индексы кластеризованы", "кластеризовать индекс"? Это вы придумали, вы и объясните пожалуйста. MBG"пример использования временных объектов для построения отчета (выдернул из функции на pltcl)" Вместе с комментариями.Я стараюсь искать решение на SQL, и чаще всего оно находится. Но, должен признать, иногда приходится использовать plpgsql или другие процедурные языки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 17:16 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
Andrey DaeronЯ бы не стал относить термин "кластер" к хранению индекса. ИМХО это неверно по сути своей. Таблица может быть упорядачена по индексу, в таком случае индекс называется кластерным, а таблица кластеризированной. Но хранится он все равно в виде бинарного дерева со ссылками на страницы, в которых возможно есть данные. Скорее всего при перестроении произойдет перебалансиорвка дерева и индекс станет более аптимальным. Дерево это логическая структура и на диске может храниться по-разному. Насчет терминологии замечу, что термин кластеризация может использоваться в смысле группировки по значению элемента данных, по значению индекса или группировки при записи на диск и для немонотонной функции индекса эти смыслы не совпадают для таблицы (последовательные значения элементов набора данных могут соответствовать "далеким" значениям индекса и наоборот). В том смысле, что "кластеризованная" таблица и "кластеризованная по индексу" не равноценные термины. Тем не менее, термин "кластеризованная" все же используется. А насчет индекса - может и на самом деле лучше звать его кластерным, так хотя бы видно, что' есть причина (порядок значений индекса), а что' - следствие (физическое хранение данных таблицы). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 17:32 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat MBG"пример использования временных объектов для построения отчета (выдернул из функции на pltcl)" Вместе с комментариями.Я стараюсь искать решение на SQL, и чаще всего оно находится. Но, должен признать, иногда приходится использовать plpgsql или другие процедурные языки. И пользовательский интерфейс на sql пишите? Круто :-) В моем варианте БД пользовательские сессии хранятся в базе, так что функция на pltcl читает из сессии параметры и создает соответствующие виды и таблицы, которые нужны для вывода отчета. В итоге вся логика обработки данных хранится в базе, написать набор тестов для любого отчета пара пустяков (для требуемых наборов значений повторять: записать в сессию пользователя тестовые значения, вызвать функцию построения отчета, вычислить некий хэш для проверки правильности работы). Притом набор тестов также можно зашить в pltcl функцию и вызывать при необходимости. Так что прикладному программисту вряд ли удастся нарушить правильность работы системы, максимум, что удастся, это что функция создания отчета вернет ошибку (это если совсем уж ерунду в сессию записать). Приведенные примеры можно и из консоли напрямую вызвать, вовсе не обязательно из функции. Привел "как есть", чтобы было видно, куда какие условия подставляются. Но при желании можно заместо переменных забить тестовые значения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 17:47 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
MBGНасчет терминологии замечу, что термин кластеризация может использоваться в смысле группировки по значению элемента данных, по значению индекса или группировки при записи на диск и для немонотонной функции индекса эти смыслы не совпадают для таблицы (последовательные значения элементов набора данных могут соответствовать "далеким" значениям индекса и наоборот).Давайте в разделе PostgreSQL этого форума придерживаться терминологии, принятой в постгресе... MBG"кластеризованная" таблица и "кластеризованная по индексу" не равноценные терминыВ постгресе это одно и то же, потому что нельзя кластеризовать таблицу иначе чем по индексу. ( PS: Можно кластеризовать таблицу, а потом удалить индекс. :-) Таблица останется кластеризованной. По функционалу, который соответствует индексу. ) MBGтак хотя бы видно, что есть причина (порядок значений индекса), а что - следствие (физическое хранение данных таблицы).Наконец-то. Позвольте стоя отдать должные аплодисменты вашему верному утверждению. MBGИ пользовательский интерфейс на sql пишите? Круто :-)Скорее наоборот. У нас много (возможно слишком много) логики находится в приложении. Но как-то (другой) программист написал функцию на plpgsql, с течением времени ее логику приходилось усложнять, потом еще. Потом поняли, что делать очередное усложнение средствами plpgsql слишком сложно, и перенесли ее в приложение переписав на perl, после чего нервы она больше не трепала. :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 18:03 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
LeXa NalBat MBGИ пользовательский интерфейс на sql пишите? Круто :-)Скорее наоборот. У нас много (возможно слишком много) логики находится в приложении. Но как-то (другой) программист написал функцию на plpgsql, с течением времени ее логику приходилось усложнять, потом еще. Потом поняли, что делать очередное усложнение средствами plpgsql слишком сложно, и перенесли ее в приложение переписав на perl, после чего нервы она больше не трепала. :-) Когда-то сам писал на plpgsql, потом логика стала сложной и перешел на pltcl. А приложение переписали с perl на tcl и настало всеобщее счастье :-) Так, ради смеха - код на тикле код в три раза меньше перлового по объему сразу после переноса получился. Потом еще немного сократили. Держать логику в базе хорошо, поскольку и целостность данных в порядке, и быстродействие высокое, и код простой. А вот создание интерфейса, обработку действий пользователя, форматирование таблиц и построение графиков действительно удобно делать в приложении. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 18:12 |
|
||
|
Вдруг стал медленно выполняться запрос:
|
|||
|---|---|---|---|
|
#18+
MBG Дерево это логическая структура и на диске может храниться по-разному. Факт. MBG Насчет терминологии замечу, что термин кластеризация может использоваться в смысле группировки по значению элемента данных, по значению индекса или группировки при записи на диск и для немонотонной функции индекса эти смыслы не совпадают для таблицы (последовательные значения элементов набора данных могут соответствовать "далеким" значениям индекса и наоборот). Если уж формализироваться, то Wiki . А у ПГ вообще маленький частный подслучай. Он даже не могет сам поддерживать степень клатеризированности таблицы. Наверно итог по теме кластеризации. После нее - таблице явно хорошеет индексу по которому прошла кластеризация таблицы - тоже. Все остальные индексы нервно курят в сторонке, с возможным ухудшением ситуации. Процесс кластеризации ИМХО происходит примерно так: 1. Делается копия таблицы - времянка. 2. Туда заливается ORDER BY [index] данные. 3. На времянку создаются индексы. 4. На времянку создаются (или может просто перекидываются) все стальные DDL объекты (вьюги, триггера, форейны, рули и т.д.) 5. Старая табла дропается каскадом/просто дроп. 6. Новая табла переименовывается 7. Коммит. И этого алгоритма все все достоинства и недостатки. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 09.07.2007, 21:18 |
|
||
|
|

start [/forum/topic.php?all=1&fid=53&tid=2005296]: |
0ms |
get settings: |
10ms |
get forum list: |
19ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
66ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
137ms |
get tp. blocked users: |
1ms |
| others: | 234ms |
| total: | 490ms |

| 0 / 0 |
