Форум: "Базы";
Текущий архив: 2005.01.02;
Скачать: [xml.tar.bz2];
ВнизКластерный индекс Найти похожие ветки
← →
alehan (2004-12-03 12:59) [0]Можно ли как-то заставить Interbase (Firebird) физически переупорядочить данные в таблице исходя из какого-нибудь индекса к ней?
Ситуация такая: есть отношение "много-ко-многу", таблицаcreate table REF_TABLE(
ID1 integer not null,
ID2 integer not null)
уже содержит ~5 млн. записей, которые заносились так:
1. Добавляется порция записей у которой ID2 равно 1. ID1 при этом разные.
2. Потом добавляется другая порция записей у которой ID2 равно 2. ID1 при этом опять разные.
3. Потом добавляется другая порция записей у которой ID2 равно 3. ID1 при этом опять разные.
и. т.д.
Индексы есть по обоим полям. Индекс по ID2 при таком методе заполнения таблицы получается как-бы "кластерным".
Запросы в основном имеют видselect * from ref_table where ID1=:x
. И выполняются с заметными тормозами. Тормоза пропорциональны кол-ву возвращаемых записей.
Если пересобрать таблицу:create table REF_TABLE_2(ID1 integer, ID2 integer);
(через процедуру)
insert into REF_TABLE_2 select * from REF_TABLE;
delete from REF_TABLE;
insert into REF_TABLE select * from REF_TABLE_2 order by ID1;
то теже запросы будут выполнятся на порядок быстрее.
Вот бы при backup-е можно было указать в каком порядке извлекать данные из таблицы... Но всё равно это не выход. Backup\Restore, как и вышеприведённая "пересборка" таблицы требует значительного времени и отключения юзеров... А они даже ночью сидят...
Сталкивался ли кто с подобной ситуацией?
← →
Johnmen © (2004-12-03 13:06) [1]>Запросы в основном имеют вид select * from ref_table where
>ID1=:x. И выполняются с заметными тормозами. Тормоза
>пропорциональны кол-ву возвращаемых записей.
А что там с индексом по ID1 ?
← →
Sergey13 © (2004-12-03 13:13) [2]А какова селективность у ID1? Может там десяток значений всего.
>Тормоза пропорциональны кол-ву возвращаемых записей.
А в цифирях это скока запись/секунда?
← →
Sergey13 © (2004-12-03 13:29) [3]>Индексы есть по обоим полям.
Я бы сделал по 2 сразу ID1,ID2 - это ж первичный ключ будет. Не так?
>Запросы в основном имеют вид select * from ref_table where ID1=:x.
А нафига? Это же ссылки? Упростил для наглядности? Случайно не так выглядит "рабочий запрос"
select * from som_table where ID in (select ID2 from ref_table where ID1=:x)
← →
alehan (2004-12-03 13:30) [4]ID1 принимает значения в диапазоне 1..30000, количество повторений одного и того же значения ID1 в REF_TABLE варьируется от 1 до 10000.
Чаще конечно 1 или 2 раза (более половины значений ID1), но некоторые повторяются до 10000. Пользователей они интересуют почему больше всего.
Скорость, ну где-то 1000 Запись/секунда. Я так понимаю, сколько записей, столько и страниц должнен считать Interbase
← →
Johnmen © (2004-12-03 13:31) [5]>Sergey13 © (03.12.04 13:29) [3]
>"рабочий запрос"
>select * from som_table where ID in (select ID2 from ref_table where ID1=:x)
:)))
← →
Johnmen © (2004-12-03 13:34) [6]>alehan (03.12.04 13:30) [4]
>Я так понимаю, сколько записей, столько и страниц должнен считать Interbase
Если одна запись занимает "ровно одну" страницу. Но это вряд ли...:)
← →
alehan (2004-12-03 13:38) [7]
> Sergey13
Не... сначала запрос выглядел так:select * from
ref_table
join some_table on ID=ID2
where ID1=:x
Клиент на долго задумывался и не реагировал на пользователя. Потом я додумался делать так:select ID2 from ref_table where ID1=:x
, запоминал что он вернёт и пользователь видел перед собойselect * from some_table where ID in (список)
. Список - не более ~500 разумеется.
← →
alehan (2004-12-03 13:44) [8]
> Johnmen
При описанном мною способе заполнения таблицы, получается так, что на одной странице данных обычно не более одной-двух записей, у которых ID1=:x. Поэтому запросwhere ID1=:x
вынужден открывать страницу, считывать с ней одну - две подходящие записи и идти к следующей странице...
← →
Johnmen © (2004-12-03 13:44) [9]А зачем вообще получать значения ссылочных ключей из таблицы связи ? В чём фишка ?
(а ключи-то есть ?)
← →
Johnmen © (2004-12-03 13:45) [10]>alehan (03.12.04 13:44) [8]
Хм... О какой странице речь ?
← →
alehan © (2004-12-03 13:53) [11]
> Johnmen
В файле базы данных Interbase. Страница данных. Размером 4096 байт. В которой хранятся данные из REF_TABLE.
← →
Sergey13 © (2004-12-03 13:53) [12]2[7] alehan (03.12.04 13:38)
>Потом я додумался делать так
ИМХО, это ты погорячился. 8-) Попробуй вернуться к первому варианту и построй индекс ID1,ID2. Я не уверен про оптимизатор ИБ, но Оракул бы при этом вообще не читал бы таблицу, только индекс.
← →
Johnmen © (2004-12-03 14:03) [13]>alehan © (03.12.04 13:53) [11]
Понятно. Тогда пусть это тебя не тревожит.
"Кесарю - кесарево, слесарю - слесарево" (с)
А что по поводу [9] ?
← →
alehan © (2004-12-03 14:03) [14]
> Sergey13
Д-мя... Зря я так упростил ситуацию, когда задавал вопрос. Вообще-то индекс действительно не по ID1, а по ID1,ID2. К тому же уникальный.
Спасибо, буду пробовать...
← →
alehan © (2004-12-03 14:08) [15]
> Johnmen [9]
Да Сергей мне уже сказал что фишки тут особой нет. Просто думал один "тяжёлый" запрос разбить на серию "лёгких".
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2005.01.02;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 0.032 c