powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Informix [игнор отключен] [закрыт для гостей] / Как правильно построить индексы для соединения двух таблиц по двум полям?
25 сообщений из 32, страница 1 из 2
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33372495
win-kim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Такая задача:

Есть две таблички, в которые я для примера переливаю записи:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
create temp table t1(f1 varchar( 50 ), f2 int8);
create temp table t2(f1 varchar( 50 ), f2 int8);

insert into t1
select referens, rs_rownum from table;
insert into t2
select referens, rs_rownum from table;

Затем создаю по 2 индекса в каждой табличке:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
create index idx_t1_f1 on t1(f1);
create index idx_t1_f2 on t1(f2);
update statistics medium for table t1;

create index idx_t2_f1 on t2(f1);
create index idx_t2_f2 on t2(f2);
update statistics medium for table t2;

При выполнении выборки, оптимизатор игнорирует индекс:
Код: plaintext
1.
2.
3.
select 
count(*) from t2 A, t1
where A.f1=t1.f1 and A.f2=t1.f2;
Если указывать директивы AVOID_INDEX и т.д., то оптимизатор начинает использовать индекс, но на производительность это сказывается отрицательно.

Пропобовал создавать составной индекс, не помогает :(
Код: plaintext
1.
2.
create index idx_t1_f1_f2 on t1(f1, f2);
create index idx_t2_f1_f2 on t2(f1, f2);

Подскажите пожалуйста, что не так?

best regards,
win-kim
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33372526
Фотография Журавлев Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
win-kim
...
Подскажите пожалуйста, что не так?

Информикс 7-мой? Тогда не так это varchar(50). Пробуй с char(50).

Если не 7-мой тогда таблички очень маленькие и секскан дешевле, попробуй не собирать статистику. И покажи план для вариантов со статистикой и без.
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33372576
win-kim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ver Informix 9.4

количество записей в таблицах: 20319

План выполнения запроса без обновления статистики в таблицах(теперь показывает, что использует индексы, и трудозатраты минимальные, но реально также долго выполняется (60 секунд)):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
QUERY:

------
select 
count(*) from t2 A, t1
where A.f1=t1.f1 and A.f2=t1.f2;

Estimated Cost:  3 

Estimated # of Rows Returned:  1 

   1 ) informix.a: SEQUENTIAL SCAN

   2 ) informix.t1: INDEX PATH

        Filters: informix.a.f1 = informix.t1.f1 

    ( 1 ) Index Keys: f2   (Serial, fragments: ALL)

        Lower Index Filter: informix.a.f2 = informix.t1.f2 

NESTED LOOP JOIN

План выполнения запроса с обновлением статистики в таблицах:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
QUERY:

------
select 
count(*) from t2 A, t1
where A.f1=t1.f1 and A.f2=t1.f2;

Estimated Cost:  10189 

Estimated # of Rows Returned:  1 

   1 ) informix.a: SEQUENTIAL SCAN

   2 ) informix.t1: SEQUENTIAL SCAN


DYNAMIC HASH JOIN 

    Dynamic Hash Filters: (informix.a.f1 = informix.t1.f1 AND informix.a.f2 = informix.t1.f2 )

Еще одно примечание, у меня в поле f1 повторяются значения, а в поле f2 значения уникальны в пределах f1. Т.е. как бы составной ключ f1, f2, которого нет.

best regards,
win-kim
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33372589
Фотография Журавлев Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
win-kimver Informix 9.4

количество записей в таблицах: 20319

А count(*) сколько показывает-то?

для 20319 строк HASH JOIN (у вас optcomind ведь 2) это правильно и индексы не нужны.
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33372594
Фотография Журавлев Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кстати AVOID_INDEX это как раз директива НЕ использовать индекс.
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33372657
win-kim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
select 
count(*) from t2 A, t1
where A.f1=t1.f1 and A.f2=t1.f2;
Код: plaintext
1.
20319

Журавлев Денис
для 20319 строк HASH JOIN (у вас optcomind ведь 2) это правильно и индексы не нужны.


Я думаю, что запрос на соединении двух таблиц по 20 тыс строк, который выполняется пол минуты это неправильно.

По одному полю соединение таблиц в 1 млн строк идет быстрее. Все таки нужно как то сделать быстрее.

Журавлев Денис
Кстати AVOID_INDEX это как раз директива НЕ использовать индекс.


Я имел ввиду FULL_INDEX

best regards,
win-kim
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33372739
Valentyn Pidburtnyi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
win-kimЯ думаю, что запрос на соединении двух таблиц по 20 тыс строк, который выполняется пол минуты это неправильно.
Попробуй тип поля поменять на char(50). Для индекса фиксированная длина поля - важно, вроде...

Сама по себе задача построения индекса по строковому полю с длиной 50 а потом соединение по этому индексу - очень тяжелая задача для сервера...
Оправдываться (т.е. соединение будет происходить быстрее чем по скану) использование индекса начнет только на очень больших размерах таблиц. А до тех пор впустую будут тратиться системные ресурсы на поддержание актуальности индекса (а это очень много, учитывая по каким полям он построен).
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33372749
Фотография Журавлев Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
win-kim
20319

Тогда второй план точно правильный. Индексы не нужны. Статистика нужна. NONPDQMEMORY нужна.

win-kim
По одному полю соединение таблиц в 1 млн строк идет быстрее. Все таки нужно как то сделать быстрее.
А в результате тоже мульон и тоже считаешь count*? План покажи. Не верится что-то.

win-kim
Я имел ввиду FULL_INDEX
Такого хинта вообще нет.
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33372757
Фотография Журавлев Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Valentyn Pidburtnyi
Попробуй тип поля поменять на char(50). Для индекса фиксированная длина поля - важно, вроде...

Нет, ему пофигу. В индексе будет фиксированная что для char что для varchar.
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33372935
win-kim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Журавлев Денис win-kim
20319

Тогда второй план точно правильный. Индексы не нужны. Статистика нужна. NONPDQMEMORY нужна.

win-kim
По одному полю соединение таблиц в 1 млн строк идет быстрее. Все таки нужно как то сделать быстрее.
А в результате тоже мульон и тоже считаешь count*? План покажи. Не верится что-то.

win-kim
Я имел ввиду FULL_INDEX
Такого хинта вообще нет.

извиняюсь, снова опечатался
AVOID_FULL
FULL

А на счет млн строк, тама идет соединение таблички в 1 млн строк с табличкой в 50 тыс строк идет около 20 секунд (вставка в другую). Но не в этом суть, меня не устраивает скорость по соединению по двум полям.

заменил varchar(50) на char(50), та же фигня.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
QUERY:

------
select 
count(*) from t2 A, t1
where A.f1=t1.f1 and A.f2=t1.f2;

Estimated Cost:  10899 

Estimated # of Rows Returned:  1 

   1 ) informix.a: SEQUENTIAL SCAN
   2 ) informix.t1: SEQUENTIAL SCAN

DYNAMIC HASH JOIN 

    Dynamic Hash Filters: (informix.a.f1 = informix.t1.f1 AND informix.a.f2 = informix.t1.f2 )

Журавлев Денис
NONPDQMEMORY нужна.


а что это?

best regards,
win-kim
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33373009
Фотография Журавлев Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
win-kim
Журавлев Денис
NONPDQMEMORY нужна.


а что это?
При хеш джойне будет хештаблица размером 60 байт(строка)*20319 ~ 1,6 мегабайта наверняка в память сессии она не влезает и будет лежать в темпе.

В 9.40.xC4 появился параметр DS_NONPDQ_QUERY_MEM который позволяет увеличить кол-во памяти для сессии.
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33373054
Фотография Журавлев Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
win-kim
А на счет млн строк, тама идет соединение таблички в 1 млн строк с табличкой в 50 тыс строк идет около 20 секунд (вставка в другую).
Там в результате соединения получается сколько строк (сколько инсертятся)?


win-kim
Но не в этом суть, меня не устраивает скорость по соединению по двум полям.
Кол-во полей ни на что не влияет, я постоянно вижу как таблицы соединяют по десяти полям и что? По моему оба плана абсолютно нормальные и индекс нужен либо на одной из таблиц (NL) как в первом случае, либо не нужен вообще (HJ) как во втором (но тут нужна low статистика).

ЗЫЖ Естественно поможет pdq, во втором случае (HJ) ускорится сильно, в первом меньше -- распаллелится только первый шаг (секскан).
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33373095
win-kim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Журавлев Денис win-kim
А на счет млн строк, тама идет соединение таблички в 1 млн строк с табличкой в 50 тыс строк идет около 20 секунд (вставка в другую).

Там в результате соединения получается сколько строк (сколько инсертятся)?


Точно не помню, окола 100 тыс.

Журавлев Денис win-kim
Но не в этом суть, меня не устраивает скорость по соединению по двум полям.
Кол-во полей ни на что не влияет, я постоянно вижу как таблицы соединяют по десяти полям и что? По моему оба плана абсолютно нормальные и индекс нужен либо на одной из таблиц (NL) как в первом случае, либо не нужен вообще (HJ) как во втором (но тут нужна low статистика).

Блин, значит быстрее никак? Это риторический вопрос, отвечать не надо :(
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33373100
onstat-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
win-kimТакая задача:

Есть две таблички, в которые я для примера переливаю записи:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
create temp table t1(f1 varchar( 50 ), f2 int8);
create temp table t2(f1 varchar( 50 ), f2 int8);

insert into t1
select referens, rs_rownum from table;
insert into t2
select referens, rs_rownum from table;

Затем создаю по 2 индекса в каждой табличке:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
create index idx_t1_f1 on t1(f1);
create index idx_t1_f2 on t1(f2);
update statistics medium for table t1;

create index idx_t2_f1 on t2(f1);
create index idx_t2_f2 on t2(f2);
update statistics medium for table t2;

При выполнении выборки, оптимизатор игнорирует индекс:
Код: plaintext
1.
2.
3.
select 
count(*) from t2 A, t1
where A.f1=t1.f1 and A.f2=t1.f2;
Если указывать директивы AVOID_INDEX и т.д., то оптимизатор начинает использовать индекс, но на производительность это сказывается отрицательно.

Пропобовал создавать составной индекс, не помогает :(
Код: plaintext
1.
2.
create index idx_t1_f1_f2 on t1(f1, f2);
create index idx_t2_f1_f2 on t2(f1, f2);

Подскажите пожалуйста, что не так?

best regards,
win-kim



1. Думаю скорость обьединения возрастет если составной индекс построить наоборот
create index idx_t1_f1_f2 on t1(f2, f1);
create index idx_t2_f1_f2 on t2(f2, f1);
Но это зависит от статистического распределения значений в поле f2.

2. Насколько я помню в каких то версиях был баг или фича при использовании
индексного поиска по плям varchar.
А при использовании типа char все строки при храненнии будут дополненны пробелами до полной длины(50 байт в вашем случае). В результате в случае NESTED LOOP JOIN сервер буде сравнивать пробелы,
а в случае HASH JOIN уникальность результата hash функции
будет непредсказуема, и реальная стоимось может на порядки отличаться
от того что предполагает план запроса, здесь cможет помочь только
update statistics high и то не всегда.

3.Думаю нужно подумать о
искуственных ключах. В худшем случае вы потеряете 8 байт в каждой записи,
зато получите прогнозированную производительнось, которая будет граздо выше текущей.
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33373118
GVF112GVF
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Может все дело в групповом операторе COUNT или SUM или ...
Попробуй в целевом списке задать имя поля .... результат соединение таблиц
разместить вв времменой таблице ... далее используй COUNT для результирующей выборки ....:)

GVF112
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33373122
win-kim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
onstat-
win-kim
Такая задача:

Есть две таблички, в которые я для примера переливаю записи:

create temp table t1(f1 varchar(50), f2 int8);
create temp table t2(f1 varchar(50), f2 int8);

insert into t1
select referens, rs_rownum from table;
insert into t2
select referens, rs_rownum from table;


Затем создаю по 2 индекса в каждой табличке:

create index idx_t1_f1 on t1(f1);
create index idx_t1_f2 on t1(f2);
update statistics medium for table t1;

create index idx_t2_f1 on t2(f1);
create index idx_t2_f2 on t2(f2);
update statistics medium for table t2;


При выполнении выборки, оптимизатор игнорирует индекс:

select
count(*) from t2 A, t1
where A.f1=t1.f1 and A.f2=t1.f2;

Если указывать директивы AVOID_INDEX и т.д., то оптимизатор начинает использовать индекс, но на производительность это сказывается отрицательно.

Пропобовал создавать составной индекс, не помогает :(

create index idx_t1_f1_f2 on t1(f1, f2);
create index idx_t2_f1_f2 on t2(f1, f2);


Подскажите пожалуйста, что не так?

best regards,
win-kim




1. Думаю скорость обьединения возрастет если составной индекс построить наоборот
create index idx_t1_f1_f2 on t1(f2, f1);
create index idx_t2_f1_f2 on t2(f2, f1);
Но это зависит от статистического распределения значений в поле f2.



Построил индекс:

create index idx_t1_f2_f1 on t1(f2,f1);
update statistics medium for table t1;

create index idx_t2_f2_f1 on t2(f2,f1);
update statistics medium for table t2;


Без директивы оптимизатор индексы не использует. А с директивой стоимость запроса большая.
Вобщем результат нет.
Код: 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.
31.
QUERY:

------

select {+AVOID_FULL(t1), AVOID_FULL(t2)}count(*) from t1, t2
where t1.f1=t2.f1 and t1.f2=t2.f2;

DIRECTIVES FOLLOWED: 

AVOID_FULL ( t1 )

AVOID_FULL ( t2 )

DIRECTIVES NOT FOLLOWED: 


Estimated Cost:  11159 

Estimated # of Rows Returned:  1 

   1 ) informix.t1: INDEX PATH

    ( 1 ) Index Keys: f2 f1   (Key-Only)  (Serial, fragments: ALL)

   2 ) informix.t2: INDEX PATH

    ( 1 ) Index Keys: f2 f1   (Key-Only)  (Serial, fragments: ALL)


DYNAMIC HASH JOIN 

    Dynamic Hash Filters: (informix.t1.f1 = informix.t2.f1 AND informix.t1.f2 = informix.t2.f2 )
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33373241
Фотография Журавлев Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
win-kim(1) Index Keys: f2 f1 (Key-Only) (Serial, fragments: ALL)
(1) Index Keys: f2 f1 (Key-Only) (Serial, fragments: ALL)
DYNAMIC HASH JOIN

Гыгыгы (оптимайзер не обманешь). Надо было тогда его домучать use_nl.
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33373277
onstat-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ключевая фраза эта
onstat

Но это зависит от статистического распределения значений в поле f2.




win-kim
Построил индекс:
Код: plaintext
1.
2.
3.
4.
5.
create index idx_t1_f2_f1 on t1(f2,f1);
update statistics medium for table t1;

create index idx_t2_f2_f1 on t2(f2,f1);
update statistics medium for table t2;

Без директивы оптимизатор индексы не использует. А с директивой стоимость запроса большая.
Вобщем результат нет.



Если есть возможность зделайте
update statistics drop distribution;
Я непомню можно ли его делать для конкретной таблицы.

А потом
update statistics medium ....

Я сталкивался с кривой статистикой в случае если сначала
делать low, а потом переходить на medium | high
без удаления старой сратистики.

Если не поможет, нужно менять логику приложения,

Если вы даже и добьетесь удовлетворительно результата
при определенном статистическом распределении,
то другое распределение может дать замедление
на порядки особенно с использованем HASH JOIN
даже при одинаковом cost.
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33373288
Фотография Журавлев Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
onstat-
1. Думаю скорость обьединения возрастет если составной индекс построить наоборотТеоритически от этого в данном случае изменится не должно ничего.

onstat-
2. Насколько я помню в каких то версиях был баг или фича при использовании индексного поиска по плям varchar.
В семерке.

onstat-
А при использовании типа char все строки при храненнии будут дополненны пробелами до полной длины(50 байт в вашем случае).
В индексах оно и так (char) и сяк (varchar) пробелами будет дополнено.
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33373344
win-kim
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
onstat-

Если есть возможность зделайте
update statistics drop distribution;
Я непомню можно ли его делать для конкретной таблицы.

А потом
update statistics medium ....

Я сталкивался с кривой статистикой в случае если сначала
делать low, а потом переходить на medium | high
без удаления старой сратистики.

Если не поможет, нужно менять логику приложения,

Если вы даже и добьетесь удовлетворительно результата
при определенном статистическом распределении,
то другое распределение может дать замедление
на порядки особенно с использованем HASH JOIN
даже при одинаковом cost.

Как вы заметили таблички временные, поэтому я думаю операция чистки статистики не имеет смысла...
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33373357
onstat-
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Журавлев Денис onstat-
1. Думаю скорость обьединения возрастет если составной индекс построить наоборотТеоритически от этого в данном случае изменится не должно ничего.


Теоретически ничего не поменяется если строки не дополнены пробелами.

Если же занчащая часть строк состоит из 10 байт, то для того, что бы перйти
к проверке на совпадение 2 -го поля, нужно сравнить между собой
40 байт пробелов.
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33374624
Выбегалло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Че-то у вас не то получается. Мои результаты - выполняется практически мгновенно.
Код: 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.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
create table tbl (referens varchar( 50 ), rs_rownum int8);
--drop procedure popul;
create procedure popul (nrows int);
  define i int;
  delete from tbl;
  for i =  1  to nrows
    insert into tbl  values (i, i || '                              ');
  end for
end procedure;

execute procedure popul( 20319 );
create temp table t1(f1 varchar( 50 ), f2 int8);
create temp table t2(f1 varchar( 50 ), f2 int8);

insert into t1
select referens, rs_rownum from tbl ;
insert into t2
select referens, rs_rownum from tbl ;


create index idx_t1_f1 on t1(f1);
create index idx_t1_f2 on t1(f2);
update statistics medium for table t1;

create index idx_t2_f1 on t2(f1);
create index idx_t2_f2 on t2(f2);
update statistics medium for table t2;

set explain on;
select
count(*) from t2 A, t1
where A.f1=t1.f1 and A.f2=t1.f2;


QUERY:
------
select
count(*) from t2 A, t1
where A.f1=t1.f1 and A.f2=t1.f2

Estimated Cost:  8448 
Estimated # of Rows Returned:  1 

   1 ) informix.a: SEQUENTIAL SCAN

   2 ) informix.t1: INDEX PATH

        Filters: informix.a.f2 = informix.t1.f2

    ( 1 ) Index Keys: f1   (Serial, fragments: ALL)
        Lower Index Filter: informix.a.f1 = informix.t1.f1
NESTED LOOP JOIN
Informix Dynamic Server Version 9.40.TC1G2 -- On-Line -- Up 00:10:48 -- 117376
Kbytes,
никаких настроек сервера не делал, все по умолчанию.

В таком вот аксепте
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33374634
Выбегалло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Переделал процедуру на повторяющтиеся значения в f1 :
Код: 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.
create procedure popul (nrows int);
  define i int;
  delete from tbl;
  for i =  1  to nrows
    insert into tbl  values ((i mod  10 ) || '                              ', i);
  end for
end procedure;

результат :
QUERY:
------
select
count(*) from t2 A, t1
where A.f1=t1.f1 and A.f2=t1.f2

Estimated Cost:  11293 
Estimated # of Rows Returned:  1 

   1 ) informix.a: SEQUENTIAL SCAN

   2 ) informix.t1: SEQUENTIAL SCAN


DYNAMIC HASH JOIN 
    Dynamic Hash Filters: (informix.a.f2 = informix.t1.f2 AND informix.a.f1 = informix.t1.f1 ) 
Выполняется все равно моментально, на лаптопе.

В таком вот аксепте
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33374639
Выбегалло
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, в insert into tbl values ((i mod 10) || ' ', i); HTML сожрал 30 пробелов из скрипта.
В таком вот аксепте
...
Рейтинг: 0 / 0
Как правильно построить индексы для соединения двух таблиц по двум полям?
    #33374785
Фотография Журавлев Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: 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.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
OPTCOMPIND      2
create temp table t1(a varchar(50), b  serial8 );
create temp table t2(a varchar(50), b  serial8 );

insert into t1 select name, 0 from  sysobjstate; -- 10 раз 
24110 rows
insert into t2 select * from  t1;
24110 rows

1.1.
select{+ Explain} count(*)
from t1, t2
where t1.a=t2.a and t1.b=t2.b

DIRECTIVES FOLLOWED: 
EXPLAIN 
DIRECTIVES NOT FOLLOWED: 

Estimated Cost: 2
Estimated # of Rows Returned: 1

  1) informix.t1: SEQUENTIAL SCAN

  2) informix.t2: SEQUENTIAL SCAN


DYNAMIC HASH JOIN 
    Dynamic Hash Filters: (informix.t1.a = informix.t2.a AND informix.t1.b = informix.t2.b ) 

24110 rows -  16  sec.


1.2.  Set PDQPriority 100; 

select{+ Explain} count(*)
from t1, t2
where t1.a=t2.a and t1.b=t2.b

DIRECTIVES FOLLOWED: 
EXPLAIN 
DIRECTIVES NOT FOLLOWED: 

Estimated Cost: 2
Estimated # of Rows Returned: 1
 Maximum Threads: 2 

  1) informix.t1: SEQUENTIAL SCAN

  2) informix.t2: SEQUENTIAL SCAN


DYNAMIC HASH JOIN 
    Dynamic Hash Filters: (informix.t1.a = informix.t2.a AND informix.t1.b = informix.t2.b ) 

24110 rows -  0.300  sec.


1.3. Set PDQPriority 0;
create index i1 on t1(a,b); -- 2 sec
create index i2 on t2(a,b); -- 2 sec один из индексов всегда лишний
Update statistics medium for table t1;
Update statistics medium for table t2;


select{+ Explain} count(*)
from t1, t2
where t1.a=t2.a and t1.b=t2.b

DIRECTIVES FOLLOWED: 
EXPLAIN 
DIRECTIVES NOT FOLLOWED: 

Estimated Cost: 12752
Estimated # of Rows Returned: 1

  1) informix.t1: SEQUENTIAL SCAN

  2) informix.t2: INDEX PATH

    (1) Index Keys: a b   (Serial, fragments: ALL)
        Lower Index Filter: (informix.t1.b = informix.t2.b AND informix.t1.a = informix.t2.a ) 
NESTED LOOP JOIN

24110 rows -  0.700  sec.


-----------------------------------------------------------------------------------------------
create temp table t1(a varchar(50), b int8);
create temp table t2(a varchar(50), b int8);

insert into t1 select name, tabid from  sysobjstate; -- 10 раз 
24110 rows

insert into t2 select * from  t1;
24110 rows


2.1.

select{+ Explain} count(*)
from t1, t2
where t1.a=t2.a and t1.b=t2.b

DIRECTIVES FOLLOWED: 
EXPLAIN 
DIRECTIVES NOT FOLLOWED: 

Estimated Cost: 2
Estimated # of Rows Returned: 1

  1) informix.t1: SEQUENTIAL SCAN

  2) informix.t2: SEQUENTIAL SCAN


DYNAMIC HASH JOIN 
    Dynamic Hash Filters: (informix.t1.a = informix.t2.a AND informix.t1.b = informix.t2.b ) 

277500 rows -  16  sec.


2.2.  Set PDQPriority 100; 

select{+ Explain} count(*)
from t1, t2
where t1.a=t2.a and t1.b=t2.b

DIRECTIVES FOLLOWED: 
EXPLAIN 
DIRECTIVES NOT FOLLOWED: 

Estimated Cost: 2
Estimated # of Rows Returned: 1

  1) informix.t1: SEQUENTIAL SCAN

  2) informix.t2: SEQUENTIAL SCAN


DYNAMIC HASH JOIN 
    Dynamic Hash Filters: (informix.t1.a = informix.t2.a AND informix.t1.b = informix.t2.b ) 

277500 rows -  0.700  sec.  Поток один что удивляет. 

2.3. Set PDQPriority 0;
create index i1 on t1(a,b);
create index i2 on t2(a,b);
Update statistics medium for table t1;
Update statistics medium for table t2;


select{+ Explain} count(*)
from t1, t2
where t1.a=t2.a and t1.b=t2.b

DIRECTIVES FOLLOWED: 
EXPLAIN 
DIRECTIVES NOT FOLLOWED: 

Estimated Cost: 12994
Estimated # of Rows Returned: 1

  1) informix.t1: SEQUENTIAL SCAN

  2) informix.t2: SEQUENTIAL SCAN

DYNAMIC HASH JOIN 
    Dynamic Hash Filters: (informix.t1.a = informix.t2.a AND informix.t1.b = informix.t2.b ) 

277500 rows -  16  sec. Из-за неуникальности во втором поле он не хочет NL.

2.4.
select{+ Explain,  use_nl(t1) } count(*)
from t1, t2
where t1.a=t2.a and t1.b=t2.b

DIRECTIVES FOLLOWED: 
EXPLAIN 
USE_NL ( t1 )
DIRECTIVES NOT FOLLOWED: 

Estimated Cost: 27663
Estimated # of Rows Returned: 1

  1) informix.t2: SEQUENTIAL SCAN

  2) informix.t1: INDEX PATH

    (1) Index Keys: a b   (Serial, fragments: ALL)
        Lower Index Filter: (informix.t1.a = informix.t2.a AND informix.t1.b = informix.t2.b ) 
NESTED LOOP JOIN

277500 rows -  2.5  sec.

2.5.  OPTCOMPIND      0 

select{+ Explain} count(*)
from t1, t2
where t1.a=t2.a and t1.b=t2.b

DIRECTIVES FOLLOWED: 
EXPLAIN 
DIRECTIVES NOT FOLLOWED: 

Estimated Cost: 27663
Estimated # of Rows Returned: 1

  1) informix.t2: SEQUENTIAL SCAN

  2) informix.t1: INDEX PATH

    (1) Index Keys: a b   (Serial, fragments: ALL)
        Lower Index Filter: (informix.t1.a = informix.t2.a AND informix.t1.b = informix.t2.b ) 
NESTED LOOP JOIN

277500 rows -  2.5  sec.!!!!!!!!!!!!!


amd64 3000+, 512Mb, ide-hdd
winxp prof sp1
IDS 9.30.TC3

BUFFERS         2000
MAX_PDQPRIORITY 100
DS_MAX_QUERIES  32
DS_TOTAL_MEMORY 4096
DS_MAX_SCANS    1048576
OPTCOMPIND      2

В случае 2.4 я заставляю его NL (2 сек.) и это быстрее чем его HJ (16 сек.). Он выбирает HJ из-за OPTCOMPIND 2, случай 2.5 это подтверждает.

В общем индексы не нужны, все равно HJ+PDQ быстрее, плюс нет потери на создание индекса 2 сек. и сбор статистики 0.5 сек.
Хотя возможен вариант и без PDQ, но либо OPTCOMPIND 0, либо хинтами учитесь рулить правильно.

Лучший результат 0.3 секунды.
...
Рейтинг: 0 / 0
25 сообщений из 32, страница 1 из 2
Форумы / Informix [игнор отключен] [закрыт для гостей] / Как правильно построить индексы для соединения двух таблиц по двум полям?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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