Обсуждение: Подвисший запрос
Добрый день Есть такая проблема: иногда возникает "подвисший запрос". Запрос, который обычно выполняется порядка 100мс, может выполняться часами. Что приводит к заметному снижению производительности. Процесс приходится убивать. За месяц столкнулись 6 раз. Вопрос: с чем это может быть связано, какие параметры нужно замерить в след раз, чтобы локализовать проблему. Сам запрос: SELECT "v3_vacancy"."id" FROM "v3_vacancy" WHERE (("v3_vacancy"."fti_title" @@ to_tsquery('default_russian', 'официант'))AND ("v3_vacancy"."is_spam" IS FALSE ) AND ("v3_vacancy"."published_date" >= '2007-02-23 00:00:00') AND ("v3_vacancy"."is_searchable"IS TRUE ) ) AND (("v3_vacancy"."city_id" = '1') ) ORDER BY "v3_vacancy"."is_paid_top_search"DESC, "v3_vacancy"."modified_date" DESC LIMIT 30 OFFSET 120 (строка поиска каждый раз разная) Характерно использование TSearch для данной таблицы CREATE TABLE v3_vacancy ( id serial NOT NULL, ... fti_all tsvector, -- TSearch2 index для всей вакансии. fti_title tsvector, -- TSearch2 index для названия вакансии. ) WITH OIDS; CREATE INDEX v3_vacancy_fti_all_idx ON v3_vacancy USING gist (fti_all); CREATE INDEX v3_vacancy_fti_title_idx ON v3_vacancy USING gist (fti_title); SELECT * from pg_ts_cfg; ts_name | prs_name | locale -----------------+----------+-------------- default | default | C default_russian | default | ru_RU.KOI8-R simple | default | SELECT * from pg_ts_cfgmap ; ts_name | tok_alias | dict_name -----------------+--------------+----------- default | lword | {en_stem} default | nlword | {simple} default | word | {simple} default | email | {simple} default | url | {simple} default | host | {simple} default | sfloat | {simple} default | version | {simple} default | part_hword | {simple} default | nlpart_hword | {simple} default | lpart_hword | {en_stem} default | hword | {simple} default | lhword | {en_stem} default | nlhword | {simple} default | uri | {simple} default | file | {simple} default | float | {simple} default | int | {simple} default | uint | {simple} default_russian | lword | {en_stem} default_russian | nlword | {ru_stem} default_russian | word | {ru_stem} default_russian | email | {simple} default_russian | url | {simple} default_russian | host | {simple} default_russian | sfloat | {simple} default_russian | version | {simple} default_russian | part_hword | {simple} default_russian | nlpart_hword | {ru_stem} default_russian | lpart_hword | {en_stem} default_russian | hword | {ru_stem} default_russian | lhword | {en_stem} default_russian | nlhword | {ru_stem} default_russian | uri | {simple} default_russian | file | {simple} default_russian | float | {simple} default_russian | int | {simple} default_russian | uint | {simple} simple | lword | {simple} simple | nlword | {simple} simple | word | {simple} simple | email | {simple} simple | url | {simple} simple | host | {simple} simple | sfloat | {simple} simple | version | {simple} simple | part_hword | {simple} simple | nlpart_hword | {simple} simple | lpart_hword | {simple} simple | hword | {simple} simple | lhword | {simple} simple | nlhword | {simple} simple | uri | {simple} simple | file | {simple} simple | float | {simple} simple | int | {simple} simple | uint | {simple} SELECT dict_name, dict_init, dict_lexize, dict_comment from pg_ts_dict ; dict_name | dict_init | dict_lexize | dict_comment -----------------+-----------------------+-----------------------------------------+-------------------------------------------------- simple | dex_init(internal) | dex_lexize(internal,internal,integer) | Simple example of dictionary. en_stem | snb_en_init(internal) | snb_lexize(internal,internal,integer) | English Stemmer. Snowball. ru_stem | snb_ru_init(internal) | snb_lexize(internal,internal,integer) | Russian Stemmer. Snowball. ispell_template | spell_init(internal) | spell_lexize(internal,internal,integer) | ISpell interface. Must have .dict and.aff files synonym | syn_init(internal) | syn_lexize(internal,internal,integer) | Example of synonym dictionary SELECT * from pg_ts_parser; prs_name | prs_start | prs_nexttoken | prs_end | prs_headline | prs_lextype | prs_comment ----------+------------------------------+--------------------------------------------+--------------------+-------------------------------------------+------------------------+--------------------------- default | prsd_start(internal,integer) | prsd_getlexeme(internal,internal,internal) | prsd_end(internal) | prsd_headline(internal,internal,internal)| prsd_lextype(internal) | Parser from OpenFTS v0.34 PostgreSQL 8.1.8 OS Linux version 2.6.16-gentoo-r9 (gcc version 3.4.4 (Gentoo 3.4.4-r1, ssp-3.4.4-1.0, pie-8.7.8)) -- С уважением, isk mailto:isk@rdw.ru
hi all Вот два эксплэйна, не спешите копаться в их WHERE хотя это и любопытно, но не так сильно... обратите внимание что запросы отличаются ТОЛЬКО СЕЛЕКТ-ЛИСТОМ в первом запросе, который выполняется в 30 раз быстрее, выбираются все поля, а во втором, выбирается только одно поле (которое входит также и в первый запрос) и откуда же происходит такая радикальная разница в планах ???? cms1=> EXPLAIN ANALYZE SELECT * from article as a, (select st.id as stid, t1.id, t1.title FROM topic as t1, topic as st WHERE t1.up=304532 and st.trail <@ t1.trail) as t where a.topic=t.stid; QUERY PLAN Hash Join (cost=30877.69..31472.42 rows=432 width=844) (actual time=1.113..11.370 rows=745 loops=1) Hash Cond: ("outer".topic = "inner".id) -> Seq Scan on article a (cost=0.00..566.94 rows=4694 width=824) (actual time=0.006..4.328 rows=4692 loops=1) -> Hash (cost=30856.18..30856.18 rows=8604 width=20) (actual time=1.089..1.089 rows=30 loops=1) -> Nested Loop (cost=4.33..30856.18 rows=8604 width=20) (actual time=0.106..1.046 rows=30 loops=1) -> Index Scan using topic_up_idx on topic t1 (cost=0.00..346.48 rows=92 width=59) (actual time=0.017..0.041 rows=16 loops=1) Index Cond: (up = 304532) -> Bitmap Heap Scan on topic st (cost=4.33..330.45 rows=94 width=47) (actual time=0.055..0.057 rows=2 loops=16) Recheck Cond: (st.trail <@ "outer".trail) -> Bitmap Index Scan on topic_trail_idx (cost=0.00..4.33 rows=94 width=0) (actual time=0.053..0.053 rows=2 loops=16) Index Cond: (st.trail <@ "outer".trail) Total runtime: 11.886 ms (12 rows) cms1=> EXPLAIN ANALYZE SELECT t.id from article as a, (select st.id as stid, t1.id, t1.title FROM topic as t1, topic as st WHERE t1.up=304532 and st.trail <@ t1.trail) as t where a.topic=t.stid; QUERY PLAN Nested Loop (cost=6294.70..16331.26 rows=432 width=4) (actual time=227.417..314.261 rows=745 loops=1) Join Filter: ("inner".trail <@ "outer".trail) -> Bitmap Heap Scan on topic t1 (cost=2.32..322.30 rows=92 width=47) (actual time=0.036..0.076 rows=16 loops=1) Recheck Cond: (up = 304532) -> Bitmap Index Scan on topic_up_idx (cost=0.00..2.32 rows=92 width=0) (actual time=0.029..0.029 rows=16 loops=1) Index Cond: (up = 304532) -> Materialize (cost=6292.38..6339.32 rows=4694 width=43) (actual time=0.853..16.298 rows=4692 loops=16) -> Merge Join (cost=853.19..6287.69 rows=4694 width=43) (actual time=13.633..218.724 rows=4692 loops=1) Merge Cond: ("outer".id = "inner".topic) -> Index Scan using topic_pkey on topic st (cost=0.00..5130.78 rows=93527 width=47) (actual time=0.075..141.011 rows=93526 loops=1) -> Sort (cost=853.19..864.93 rows=4694 width=4) (actual time=13.536..15.858 rows=4692 loops=1) Sort Key: a.topic -> Seq Scan on article a (cost=0.00..566.94 rows=4694 width=4) (actual time=0.005..7.273 rows=4692 loops=1) Total runtime: 315.343 ms (14 rows)
Какие колонки в article?
Наверняка там varlena-типы есть (varchar, text, bytea и тд). В таких случаях работает TOAST-инг. Когда выбираем все колонки -- Постгресу приходится залезать в toast-таблицу. Если всё так, то ничего удивительного не случилось.
Про TOAST тут: http://www.postgresql.org/docs/8.2/interactive/storage-toast.html
--
Best regards,
Nikolay
Наверняка там varlena-типы есть (varchar, text, bytea и тд). В таких случаях работает TOAST-инг. Когда выбираем все колонки -- Постгресу приходится залезать в toast-таблицу. Если всё так, то ничего удивительного не случилось.
Про TOAST тут: http://www.postgresql.org/docs/8.2/interactive/storage-toast.html
On 3/28/07, silly_sad <sad@bankir.ru> wrote:
hi all
Вот два эксплэйна, не спешите копаться в их WHERE хотя это и любопытно,
но не так сильно...
обратите внимание что запросы отличаются ТОЛЬКО СЕЛЕКТ-ЛИСТОМ
в первом запросе, который выполняется в 30 раз быстрее, выбираются все
поля, а во втором, выбирается только одно поле (которое входит также и в
первый запрос)
и откуда же происходит такая радикальная разница в планах ????
cms1=> EXPLAIN ANALYZE SELECT * from article as a, (select st.id as
stid, t1.id, t1.title FROM topic as t1, topic as st WHERE t1.up=304532
and st.trail <@ t1.trail) as t where a.topic=t.stid;
QUERY PLAN
Hash Join (cost=30877.69..31472.42 rows=432 width=844) (actual
time=1.113..11.370 rows=745 loops=1)
Hash Cond: ("outer".topic = "inner".id)
-> Seq Scan on article a (cost= 0.00..566.94 rows=4694 width=824)
(actual time=0.006..4.328 rows=4692 loops=1)
-> Hash (cost=30856.18..30856.18 rows=8604 width=20) (actual
time=1.089..1.089 rows=30 loops=1)
-> Nested Loop (cost= 4.33..30856.18 rows=8604 width=20)
(actual time=0.106..1.046 rows=30 loops=1)
-> Index Scan using topic_up_idx on topic t1
(cost=0.00..346.48 rows=92 width=59) (actual time=0.017..0.041 rows=16
loops=1)
Index Cond: (up = 304532)
-> Bitmap Heap Scan on topic st (cost=4.33..330.45
rows=94 width=47) (actual time=0.055..0.057 rows=2 loops=16)
Recheck Cond: ( st.trail <@ "outer".trail)
-> Bitmap Index Scan on topic_trail_idx
(cost=0.00..4.33 rows=94 width=0) (actual time=0.053..0.053 rows=2 loops=16)
Index Cond: ( st.trail <@ "outer".trail)
Total runtime: 11.886 ms
(12 rows)
cms1=> EXPLAIN ANALYZE SELECT t.id from article as a, (select st.id as
stid, t1.id, t1.title FROM topic as t1, topic as st WHERE t1.up=304532
and st.trail <@ t1.trail) as t where a.topic=t.stid;
QUERY PLAN
Nested Loop (cost= 6294.70..16331.26 rows=432 width=4) (actual
time=227.417..314.261 rows=745 loops=1)
Join Filter: ("inner".trail <@ "outer".trail)
-> Bitmap Heap Scan on topic t1 (cost=2.32..322.30 rows=92
width=47) (actual time=0.036..0.076 rows=16 loops=1)
Recheck Cond: (up = 304532)
-> Bitmap Index Scan on topic_up_idx (cost=0.00..2.32 rows=92
width=0) (actual time=0.029..0.029 rows=16 loops=1)
Index Cond: (up = 304532)
-> Materialize (cost=6292.38..6339.32 rows=4694 width=43) (actual
time=0.853..16.298 rows=4692 loops=16)
-> Merge Join (cost=853.19..6287.69 rows=4694 width=43)
(actual time=13.633..218.724 rows=4692 loops=1)
Merge Cond: ("outer".id = "inner".topic)
-> Index Scan using topic_pkey on topic st
(cost= 0.00..5130.78 rows=93527 width=47) (actual time=0.075..141.011
rows=93526 loops=1)
-> Sort (cost=853.19..864.93 rows=4694 width=4) (actual
time=13.536..15.858 rows=4692 loops=1)
Sort Key: a.topic
-> Seq Scan on article a (cost=0.00..566.94
rows=4694 width=4) (actual time=0.005..7.273 rows=4692 loops=1)
Total runtime: 315.343 ms
(14 rows)
---------------------------(end of broadcast)---------------------------
TIP 4: Have you searched our list archives?
http://archives.postgresql.org
--
Best regards,
Nikolay
Nikolay Samokhvalov wrote: > Какие колонки в article? > Наверняка там varlena-типы есть (varchar, text, bytea и тд). В таких Есть. и много. > случаях работает TOAST-инг. Когда выбираем все колонки -- Постгресу > приходится залезать в toast-таблицу. Если всё так, то ничего > удивительного не случилось. Если это неудивительно и вы ожидали такой эффект, то скажите: какой запрос по-вашему должен быть тормознутее ? > Про TOAST тут: > http://www.postgresql.org/docs/8.2/interactive/storage-toast.html > > On 3/28/07, * silly_sad* <sad@bankir.ru <mailto:sad@bankir.ru>> wrote: > > hi all > > Вот два эксплэйна, не спешите копаться в их WHERE хотя это и любопытно, > но не так сильно... > обратите внимание что запросы отличаются ТОЛЬКО СЕЛЕКТ-ЛИСТОМ > в первом запросе, который выполняется в 30 раз быстрее, выбираются все > поля, а во втором, выбирается только одно поле (которое входит также и в > первый запрос) > и откуда же происходит такая радикальная разница в планах ???? > > > > cms1=> EXPLAIN ANALYZE SELECT * from article as a, (select st.id > <http://st.id> as > stid, t1.id <http://t1.id>, t1.title FROM topic as t1, topic as st > WHERE t1.up=304532 > and st.trail <@ t1.trail) as t where a.topic=t.stid; > > QUERY PLAN > > > Hash Join (cost=30877.69..31472.42 rows=432 width=844) (actual > time=1.113..11.370 rows=745 loops=1) > Hash Cond: ("outer".topic = "inner".id) > -> Seq Scan on article a (cost= 0.00..566.94 rows=4694 width=824) > (actual time=0.006..4.328 rows=4692 loops=1) > -> Hash (cost=30856.18..30856.18 rows=8604 width=20) (actual > time=1.089..1.089 rows=30 loops=1) > -> Nested Loop (cost= 4.33..30856.18 rows=8604 width=20) > (actual time=0.106..1.046 rows=30 loops=1) > -> Index Scan using topic_up_idx on topic t1 > (cost=0.00..346.48 rows=92 width=59) (actual time=0.017..0.041 rows=16 > loops=1) > Index Cond: (up = 304532) > -> Bitmap Heap Scan on topic st (cost=4.33..330.45 > rows=94 width=47) (actual time=0.055..0.057 rows=2 loops=16) > Recheck Cond: ( st.trail <@ "outer".trail) > -> Bitmap Index Scan on topic_trail_idx > (cost=0.00..4.33 rows=94 width=0) (actual time=0.053..0.053 rows=2 > loops=16) > Index Cond: ( st.trail <@ "outer".trail) > Total runtime: 11.886 ms > (12 rows) > > > cms1=> EXPLAIN ANALYZE SELECT t.id <http://t.id> from article as > a, (select st.id <http://st.id> as > stid, t1.id <http://t1.id>, t1.title FROM topic as t1, topic as st > WHERE t1.up=304532 > and st.trail <@ t1.trail) as t where a.topic=t.stid; > > QUERY PLAN > > > Nested Loop (cost= 6294.70..16331.26 rows=432 width=4) (actual > time=227.417..314.261 rows=745 loops=1) > Join Filter: ("inner".trail <@ "outer".trail) > -> Bitmap Heap Scan on topic t1 (cost=2.32..322.30 rows=92 > width=47) (actual time=0.036..0.076 rows=16 loops=1) > Recheck Cond: (up = 304532) > -> Bitmap Index Scan on topic_up_idx (cost=0.00..2.32 rows=92 > width=0) (actual time=0.029..0.029 rows=16 loops=1) > Index Cond: (up = 304532) > -> Materialize (cost=6292.38..6339.32 rows=4694 width=43) (actual > time=0.853..16.298 rows=4692 loops=16) > -> Merge Join (cost=853.19..6287.69 rows=4694 width=43) > (actual time=13.633..218.724 rows=4692 loops=1) > Merge Cond: ("outer".id = "inner".topic) > -> Index Scan using topic_pkey on topic st > (cost= 0.00..5130.78 rows=93527 width=47) (actual time=0.075..141.011 > rows=93526 loops=1) > -> Sort (cost=853.19..864.93 rows=4694 width=4) (actual > time=13.536..15.858 rows=4692 loops=1) > Sort Key: a.topic > -> Seq Scan on article a (cost=0.00..566.94 > rows=4694 width=4) (actual time=0.005..7.273 rows=4692 loops=1) > Total runtime: 315.343 ms > (14 rows) > > ---------------------------(end of > broadcast)--------------------------- > TIP 4: Have you searched our list archives? > > http://archives.postgresql.org > > > > > -- > Best regards, > Nikolay
Nikolay Samokhvalov wrote: > А можно схему таблиц посмотреть? Можно, но она большая. Поэтому если чо, я могу рассказать. article.up references article.id article.topic references topic.id topic.up references topic.id Схема ниже, кому не интересно может не читать. \d topic Column | Type | Modifiers -------------+-----------------------------+--------------------------------------------------------------------- id | integer | not null name | text | not null realm | text | not null guid | text | usr | text | not null grp | text | not null acl | row_acl | not null created | timestamp without time zone | not null default now() creator | text | not null updated | timestamp without time zone | not null default now() updater | text | not null exported | timestamp without time zone | not null default '1970-01-01 00:00:00'::timestamp without time zone vector | tsvector | up | integer | trail | ltree | not null layer | integer | not null pid | integer | not null default 0 score | integer | not null default 0 title | text | not null default ''::text description | text | not null default ''::text extra | text | not null default ''::text revision | integer | not null default 0 Indexes: "topic_pkey" PRIMARY KEY, btree (id) "topic_guid_idx" UNIQUE, btree (guid) "topic_name_key" UNIQUE, btree (name, pid) "topic_acl_idx" gist (acl) "topic_grp_idx" btree (grp) "topic_layer_idx" btree (layer) "topic_realm_idx" btree (realm) "topic_trail_idx" gist (trail) "topic_up_idx" btree (up) "topic_usr_idx" btree (usr) "topic_vector_key" gist (vector) \d article Column | Type | Modifiers ----------+-----------------------------+----------------------------------------------------------------------- id | integer | not null name | text | not null realm | text | not null guid | text | usr | text | not null grp | text | not null acl | row_acl | not null created | timestamp without time zone | not null default now() creator | text | not null updated | timestamp without time zone | not null default now() updater | text | not null exported | timestamp without time zone | not null default '1970-01-01 00:00:00'::timestamp without time zone vector | tsvector | up | integer | trail | ltree | not null layer | integer | not null pid | integer | not null default 0 topic | integer | not null title | text | not null default ''::text abstract | text | not null default ''::text content | text | not null default ''::text author | text | not null default ''::text start | timestamp without time zone | not null default now() stop | timestamp without time zone | not null default (date_trunc('day'::text, now()) + '1 day'::interval) extra | text | not null default ''::text revision | integer | not null default 0 locked | timestamp without time zone | not null default 'infinity'::timestamp without time zone locker | text | not null default 'anonymous'::text score | integer | not null default 0 type | integer | not null default 0 section | integer[] | not null default '{}'::integer[] Indexes: "article_pkey" PRIMARY KEY, btree (id) "article_guid_idx" UNIQUE, btree (guid) "article_name_key" UNIQUE, btree (name, topic) "article_acl_idx" gist (acl) "article_grp_idx" btree (grp) "article_layer_idx" btree (layer) "article_realm_idx" btree (realm) "article_section_idx" gist (section) "article_topic_idx" btree (topic) "article_trail_idx" gist (trail) "article_up_idx" btree (up) "article_usr_idx" btree (usr) "article_vector_key" gist (vector)
Nikolay Samokhvalov wrote: >> обратите внимание что запросы отличаются ТОЛЬКО СЕЛЕКТ-ЛИСТОМ > Какие колонки в article? я вдогонку хочу ещё разх обратить ваше внимание на то как изменился план (второй по сравнению с первым) article ушёл в глубину зачем-то и если верить эксплэйну был полностью выбран без условия: > -> Sort (cost=853.19..864.93 rows=4694 width=4) (actual > time=13.536..15.858 rows=4692 loops=1) > Sort Key: a.topic > -> Seq Scan on article a (cost=0.00..566.94 > rows=4694 width=4) (actual time=0.005..7.273 rows=4692 loops=1)