powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / GIST индексы бывают опасны
3 сообщений из 3, страница 1 из 1
GIST индексы бывают опасны
    #33063192
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если в многостолбцовом GIST индексе в первом столбце много неуникальных значений, начинаются глюки. При использовании btree_gist для varchar : вплоть до неверного(!!!!) результата select-а, использующего этот индекс. Не говоря уже о значительном росте времени на доавление.

Here's smaller example of presentation bugs 1614 and 1616.
Run on PostgreSQL 8.0.1/8.0.2 on Windows and PostgreSQL 8.0.1 on Slackware 10.0 (throw
PGAdmin3)

/*
contrib/btree_gist installed
*/
/*tool function for drop table*/
create or replace function drop_try_gist() returns void as $$
begin
begin
drop table try_gist;
exception
when OTHERS then NULL;
end;
return;
end;
$$ language plpgsql;

/*tool function for fill table*/
create or replace function fill_try_gist(fields text[][],counts int[]) returns void as $$
declare
i int;
j int;
f_low int;
f_upp int;
comm text;
commt text;
begin
f_low:=array_lower(fields,2);
f_upp:=array_upper(fields,2);
comm:='insert into try_gist ("'|| array_to_string(fields[1:1][f_low:f_upp],'","') ||
'") values (';
for i in array_lower(counts,1) .. array_upper(counts,1) loop
commt=comm || array_to_string(fields[i+1 : i+1][f_low:f_upp],',') ||')';
for j in 1 .. counts loop
execute replace(commt,'#$i$#',j::text);
end loop;
end loop;
return;
end;
$$ language plpgsql;

/*testing gist with text field*/
create or replace function create_try_gist_text() returns void as $$
begin
perform drop_try_gist();
CREATE TABLE try_gist
(
id serial NOT NULL,
port varchar(30),
phone varchar(30),
CONSTRAINT try_gist_pkey PRIMARY KEY (id)
)
WITHOUT OIDS;
return;
end;
$$ language plpgsql;

create or replace function try_gist_text() returns setof int as $$
declare
i record;
begin
for i in execute '(select count(*) as c from try_gist where port=''two'' and
phone='''')' loop
return next i.c;
end loop;
execute 'create index ix_try_gist on try_gist using gist ((port::text),(phone::text)
)';
for i in execute '(select count(*) as c from try_gist where port=''two'' and
phone='''')' loop
return next i.c;
end loop;
return;
end;
$$ language plpgsql;

set enable_seqscan=off;

select create_try_gist_text();
select
fill_try_gist('{{"port","phone"},{"''''","''#$i$#''"},{"''two''","''''"}}','{2225,21}');
select * from try_gist_text();
/*returns
try_gist_text(int4)
-------------------
21
21
*/

select create_try_gist_text();
select
fill_try_gist('{{"port","phone"},{"''two''","''''"},{"''''","''#$i$#''"}}','{21,2225}');
select * from try_gist_text();
/*returns
try_gist_text(int4)
-------------------
21
0
*/

vacuum full verbose try_gist;
/* Postgres 8.0.2 Windows
INFO: vacuuming "public.try_gist"
INFO: "try_gist": found 0 removable, 2246 nonremovable row versions in 15 pages
DETAIL: 0 dead row versions cannot be removed yet.
Nonremovable row versions range from 45 to 48 bytes long.
...
INFO: index "ix_try_gist" now contains 2246 row versions in 430 pages !!!
DETAIL: 0 index pages have been deleted, 0 are currently reusable.
...
*/
/* Postgres 8.0.1 Slackware 10.0
NFO: vacuuming "public.try_gist"
INFO: "try_gist": found 0 removable, 2246 nonremovable row versions in 14 pages
DETAIL: 0 dead row versions cannot be removed yet.
...
INFO: index "ix_try_gist" now contains 2246 row versions in 628 pages !!!
DETAIL: 0 index pages have been deleted, 0 are currently reusable.
...
*/
create or replace function create_try_gist_int4() returns void as $$
begin
perform drop_try_gist();
CREATE TABLE try_gist
(
id serial NOT NULL,
portn int4,
phonen int4,
CONSTRAINT try_gist_pkey PRIMARY KEY (id)
)
WITHOUT OIDS;
return;
end;
$$ language plpgsql;

create or replace function try_gist_int4() returns setof int as $$
declare
i record;
begin
for i in execute '(select count(*) as c from try_gist where portn=10 and phonen=0)'
loop
return next i.c;
end loop;
execute 'create index ix_try_gist on try_gist using gist ( portn,phonen )';
for i in execute '(select count(*) as c from try_gist where portn=10 and phonen=0)'
loop
return next i.c;
end loop;
return;
end;
$$ language plpgsql;

select create_try_gist_int4();
select fill_try_gist('{{"portn","phonen"},{"0","#$i$#"},{"10","0"}}','{2225,21}');
select * from try_gist_int4();
/*returns right, but works (on creating index) 6 seconds in 8.0.2/Windows and >18
seconds on 8.0.1/Slackware*/

vacuum full verbose try_gist;
/* Postgres 8.0.2 Windows
INFO: vacuuming "public.try_gist"
INFO: "try_gist": found 0 removable, 2246 nonremovable row versions in 15 pages
DETAIL: 0 dead row versions cannot be removed yet.
INFO: index "ix_try_gist" now contains 2246 row versions in 7603 pages !!!!!!!!
DETAIL: 0 index pages have been deleted, 0 are currently reusable.
*/
/* Postgres 8.0.1 Slackware 10.0
INFO: vacuuming "public.try_gist"
INFO: "try_gist": found 0 removable, 2246 nonremovable row versions in 13 pages
DETAIL: 0 dead row versions cannot be removed yet.
...
INFO: index "ix_try_gist" now contains 2246 row versions in 7603 pages
DETAIL: 0 index pages have been deleted, 0 are currently reusable.
*/

Пример корявый, но то,что нужно показывает. Эфект не повторился для contrib/seg (хотя, может не внимательно смотрел). Эфект разрастания индекса и времени инсерта повторился для contrib/intarray: окончания вставки 20000 строк я не дождался за 10 минут.

Интересно, что в примере для text ( где пропадают строки), если делать select только по полю port, строки видны. Кроме того в реальных данных (на которых столкнулся с глюком) пропала также одна строчка, где port="" и phone<>"" !!!!

Писал я письма в pqsql-bugs, просил хотя бы ответить, что баг замечен, ведутся работы - не ответили. Начинаю рассылку по форумам. Если кто реально знаком с разработчиками, прошу обратить их внимание на проблему.

Приветствутся ссылки на другие уважаемые форумы PostgreSQL.

Может я паникер?
...
Рейтинг: 0 / 0
GIST индексы бывают опасны
    #33179668
nevermnd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GiST support ведется ребятами отсюда: http://www.sai.msu.su/~megera/postgres/gist/ Напиши им лично - ответят (мне всегда отвечали).
...
Рейтинг: 0 / 0
GIST индексы бывают опасны
    #33186224
Funny_Falcon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Потеря данных в селекте не наблюдается в версии 8.0.3. Так что я спокоен.
Огромный размер индекса остался (в данном частном случае : первая колонка
слабо уникальна), но я понял, что работы ведутся, подождем версии 8.1.
...
Рейтинг: 0 / 0
3 сообщений из 3, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / GIST индексы бывают опасны
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]