powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Почему не используется индекс при самом обычном джойне?
17 сообщений из 17, страница 1 из 1
Почему не используется индекс при самом обычном джойне?
    #34036278
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем привет!

А задача предельно простая: есть две таблицы. Нужно сделать джойн этих таблиц и вывести первые две результирующие записи.
Размер этих таблиц - по 140000 записей в каждой. Запрос выполняется 15 секунд. Смотрю по плану - сервер ДБ2 при выполнения джойна не использует индексы (а использует MSJOIN вместо NLJOIN). Не могу понять, почему. Разьясните, пожалуйста, как я могу ускорить работу этого джойна?

Версия базы - DB2 8.2 (фикспак тот, который месяц назад был последним, это вроде 13-й)

Помогите пожалуйста!

А теперь подробная информация.

Запрос:
Код: plaintext
1.
2.
3.
4.
select * from ( 
    select rownumber() over(order by Document.dcm_viewFrom desc) as rownumber_, Document.*, News.*
    from News join Document on News.dcm_unid=Document.dcm_unid) 
as temp_ 
where rownumber_ <=  2 

Рисунок плана выполнения запроса находится по ссылке:
план джойна или здесь: плай джойна 2

Скрипт создания таблицы Document

Код: 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.
CREATE TABLE LIGAOL.DOCUMENT ( 
    DCM_UNID      	CHARACTER( 32 ) NOT NULL,
    ENTT_ID       	VARCHAR( 32 ),
    DCM_IDENTIFIER	CHARACTER( 12 ) NOT NULL,
    DCM_TITLE     	VARCHAR( 254 ),
    DCM_BODY      	BLOB( 5000000 ),
    DCM_CREATOR   	VARCHAR( 62 ),
    DCM_DATE      	TIMESTAMP,
    DCM_TYPE      	INTEGER,
    DCM_ISVIEWABLE	SMALLINT,
    DCM_VIEWFROM  	TIMESTAMP,
    DCM_VIEWTO    	TIMESTAMP,
    DCM_AUTHORS   	VARCHAR( 126 ),
    PRIMARY KEY(DCM_UNID)
)
GO
ALTER TABLE LIGAOL.DOCUMENT
    ADD CONSTRAINT CC1160057360992
	UNIQUE (DCM_IDENTIFIER)
GO
ALTER TABLE LIGAOL.DOCUMENT
    ADD CONSTRAINT F_DOC2ENTT
	FOREIGN KEY(ENTT_ID) REFERENCES LIGAOL.ENTITY(ENTT_ID)
GO
CREATE INDEX LIGAOL.DCM_FV_ENID
    ON LIGAOL.DOCUMENT(DCM_VIEWFROM DESC, ENTT_ID)  PCTFREE  10  MINPCTUSED  10 
GO
CREATE INDEX LIGAOL.DOC2ENTT_FK
    ON LIGAOL.DOCUMENT(ENTT_ID)
GO

Скрипт создания таблицы NEWS:

Код: 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.
CREATE TABLE LIGAOL.NEWS ( 
    DCM_UNID         	CHARACTER( 32 ) NOT NULL,
    RBC_ID           	INTEGER,
    NWS_TOP          	SMALLINT,
    NWS_FIO          	VARCHAR( 512 ),
    NWS_ANNOTATION   	VARCHAR( 2048 ),
    NWS_LAWESCORT    	CLOB( 65000 ),
    NWS_CONTACTINFO  	CLOB( 16000 ),
    NWS_SHOWSIGNATURE	SMALLINT,
    NWS_PICTURENAME  	VARCHAR( 256 ),
    NWS_ISARCHIVE    	SMALLINT,
    PRIMARY KEY(DCM_UNID)
)
GO
ALTER TABLE LIGAOL.NEWS
    ADD CONSTRAINT F_RBC_TO_NWS
	FOREIGN KEY(RBC_ID) REFERENCES LIGAOL.RUBRIC(RBC_ID)
GO
ALTER TABLE LIGAOL.NEWS
    ADD CONSTRAINT FK24FEF311B2BCF5
	FOREIGN KEY(DCM_UNID) REFERENCES LIGAOL.DOCUMENT(DCM_UNID)
GO
CREATE INDEX LIGAOL.RBC_TO_NWS_FK
    ON LIGAOL.NEWS(RBC_ID)
GO

Почему DB2 не использует индекс при джойне?

Всем заранее спасибо!
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34036282
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, статистика вся построена и актуальна. Вот она:
Статистика индекса по Document.dcm_unid и Статистика индекса по News.dcm_unid
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34036581
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.

Создайте индекс по полю news.dcm_unid, соберите статистику.
И попробуйте
Код: plaintext
1.
2.
3.
4.
select * 
from News 
join Document on News.dcm_unid=Document.dcm_unid
order by Document.dcm_viewFrom desc
fetch first  2  rows only;
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34041040
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Mark BarinsteinЗдравствуйте.

Создайте индекс по полю news.dcm_unid, соберите статистику.
И попробуйте
Код: plaintext
1.
2.
3.
4.
select * 
from News 
join Document on News.dcm_unid=Document.dcm_unid
order by Document.dcm_viewFrom desc
fetch first  2  rows only;

По полю dcm_unid присутствует первичный ключ. Статистика собрано. Выполняю Ваш запрос. Получаю 6 секунд на выполение этого запроса, и следующий план:
План выполнения джойна
Как видите, план фактически тот же самый.
Подскажите, что я могу сделать, чтобы этот запрос работал быстрее?
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34041133
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ничто так не улучшает производительность как перепроектирование.
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34041157
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Используйте конструкцию With и Fetch first засуньте куда-нить внутрь.
Чтоб сначала отфильтровалось некоторое число записей, а потому ток джойнилось, а то у вас сначала все выбирается, всё джойнится, а потом ток 2 записи берется.
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34041184
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что касается ф-ции rownumber(), то лучше их вообще не юзать для приложений , которые должны возвращать данные быстро.
Если есть страстное желание пронумеровать записи в запросе, то напишите свою собственную функцию на C. Здесь были примеры подобного рода.
Опять же, чтобы ограничивать выборку лучше на самом начальном этапе, и при помощи fetch first. А чтобы добиться правильносй сортировки юзайте ORDER BY ORDER OF.
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34041201
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Какой план запроса у вас при (статистика на индекс LIGAOL.DCM_FV_ENID должна быть заранее собрана):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
with t as 
(
select 
from LIGAOL.DOCUMENT
order by dcm_viewFrom desc
fetch first  2  rows only
)
select * from t;
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34041206
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Упс!
разумеется
Код: plaintext
select DCM_UNID from ...
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34041276
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выполнился Ваш запрос очень быстро. План вот:
план запроса
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34041447
Alexander Mozhaev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VetalВыполнился Ваш запрос очень быстро. План вот:
план запроса

У тебя сколько записей в таблице, они все помещаются в памяти? - да, зачем тогда индекс использовать.
Оптимизатор у нас "умный":)
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34041468
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexander Mozhaev VetalВыполнился Ваш запрос очень быстро. План вот:
план запроса

У тебя сколько записей в таблице, они все помещаются в памяти? - да, зачем тогда индекс использовать.
Оптимизатор у нас "умный":)
В таблицах по 200 000 записей. Причем в каждой из них есть блоб килобайт так на 10-20...
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34041499
Alexander Mozhaev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попробуй убрать из запроса "where rownumber_ <= 2" и посмотреть план запроса
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34041522
Vetal
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexander MozhaevПопробуй убрать из запроса "where rownumber_ <= 2" и посмотреть план запроса
Выполнил следующий запрос:
Код: plaintext
1.
2.
3.
select * from ( 
    select rownumber() over(order by Document.dcm_viewFrom desc) as rownumber_, Document.*, News.*
    from News join Document on News.dcm_unid=Document.dcm_unid) 
as temp_ 
План получился такой:
план запроса
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34041546
Mark Barinstein
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
А такого:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
with t as 
(
select DCM_UNID
from LIGAOL.DOCUMENT
where dcm_viewFrom<current timestamp
order by dcm_viewFrom desc
fetch first  2  rows only
)
select * from t;
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34041581
Alexander Mozhaev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ты rownumber_ еще где-то используешь кроме как для отсечения строк?

Это тоже самое только без rownumber_
select
Document.*, News.*
from Document
inner join
News
on Document.dcm_unid=News.dcm_unid
order by Document.dcm_viewFrom desc

Добавь потом:
fetch first 2 rows only
...
Рейтинг: 0 / 0
Почему не используется индекс при самом обычном джойне?
    #34043389
gals
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
По моему, план запроса оптимален.
Вы хотите вывести все поля из двух таблиц. Серверу дешевле произвести полное сканирование таблицы с последующей сортировкой, нежели обход по индексу и чтение таблицы.
Ваш первый план запроса показывает, что самым затратным является не MSJOIN(7), а SORT(11)+SORT(19). Причем, SORT(19) в большей степени.

Попробуйте в первой выборке отобрать только поле связывания:
Код: plaintext
1.
2.
SELECT Document.dcm_unid 
FROM News JOIN Document ON News.dcm_unid=Document.dcm_unid
FETCH FIRST  2  ROWS ONLY
Этот запрос явно будет использовать только индексы без обращения к таблицам.
После этого можно сделать выборку всех данных из двух таблиц.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / IBM DB2, WebSphere, IMS, U2 [игнор отключен] [закрыт для гостей] / Почему не используется индекс при самом обычном джойне?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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