powered by simpleCommunicator - 2.0.41     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Что касается планирования
1 сообщений из 1, страница 1 из 1
Что касается планирования
    #32017860
Valk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ниже я привожу ситуацию с которой столкнулся и свои по ее поводу
рассуждения(наблюдения) (несостоятельные, в виду того, что они ни к чему не привели).
Прошу Ваших разъяснений. С уважением, Валентин.

Вот такой запрос (предполагается связь BaseLKart->>LKart):
SELECT
FROM lKart T ,BaseLKart B
WHERE ((T.YEARMONTH>='200101') and (T.YEARMONTH<='200101'))
and(B.LSCHET=T.LSCHET)

IB5 выдает:
PLAN JOIN (T INDEX (RDB$FOREIGN55,RDB$PRIMARY49),B INDEX (RDB$PRIMARY47)) (*)

При этом имеем:
- Для LKart INDICES:
...
LSCHETYEARMONTH: LSCHET, YEARMONTH;
RDB$FOREIGN50: YEARMONTH, KODFLATTYPE;
RDB$FOREIGN55: YEARMONTH, KODHOUSE;
RDB$PRIMARY49: YEARMONTH, LSCHET;
...
- Для BaseLKart INDICES:
...
RDB$PRIMARY47: LSCHET;
...

Явное указание плана: JOIN (T INDEX (RDB$PRIMARY49),B INDEX (RDB$PRIMARY47)) принимается
без возражений.

Если модифицировать WHERE таким образом: (абсурдность условия не важно)
WHERE ((T.YEARMONTH>='200101') and (T.YEARMONTH<='200101')and (T.YEARMONTH='200101'))
and(B.LSCHET=T.LSCHET)
Получим:
PLAN JOIN (T INDEX (RDB$FOREIGN55,RDB$PRIMARY49, RDB$FOREIGN50),B INDEX (RDB$PRIMARY47)) (**)

Дальнейшее расширение WHERE подобным образом в PLAN'е ничего не меняет, т.к. исчерпаны
индексы, начинающиеся на YEARMONTH

В случае:
WHERE ((T.YEARMONTH>='200101') >>OR<< (T.YEARMONTH<='200101')) (***)
and(B.LSCHET=T.LSCHET)
Получаем:
PLAN JOIN (B NATURAL,T INDEX
(LSCHETYEARMONTH,RDB$PRIMARY49,RDB$FOREIGN50,RDB$FOREIGN55,RDB$PRIMARY49,RDB$FOREIGN50,RDB$FOREIGN55))
При этом, можно предположить, что IB рассуждает так:
"Принимая во внимание, что:
1. Условие отбора для LKart 'OR' а, значит, придется отдельно сканировать ее
для каждого подусловия;
2. Мне 'по барабану', что данные подусловия по одному и тому же полю и я все
равно буду проверять их отдельно при отдельном же проходе, используя отдельные
индексы(см. (*) и (**));
Посему проще пройтись по всему BaseLKart, попутно отбирая из LKart".
(Хотя, все равно не понятен хвост, причем такой длинный, после LSCHETYEARMONTH.
Кстати, если его отбросить в явном указании плана, запрос обрабатывается мгновенно,
против почти 10 секунд до начала Fetch, да и сам Fetch проходит урывками, запинаясь секунд на
5 после каждых 975 записей).
Впрочем, гипотеза о желании IB избежать лишних проходов не состоятельна в ввиду
все тех же (*) и (**).

Если к (***) явно указать:
PLAN JOIN (T INDEX (RDB$FOREIGN55,RDB$PRIMARY49),B INDEX (RDB$PRIMARY47))
IB ругается такими словами: 'index RDB$FOREIGN55 cannot be used in the specified plan'

А вот PLAN JOIN (T INDEX (RDB$PRIMARY49),B INDEX (RDB$PRIMARY47)) принимает, правда,
расширяя его до
PLAN JOIN (T INDEX (RDB$PRIMARY49, RDB$PRIMARY49),B INDEX (RDB$PRIMARY47)).

В общем, как все это интерпретировать ?
???
Объясните, пожалуйста, значение выражения типа TABLE INDEX(INDEXNAME1[, INDEXNAME2[,...]]).
Похоже, я не правильно его понимаю. А понимаю я его так:
'При обработке запроса TABLE сканируется по INDEXNAME1, затем по INDEXNAME2 и т.д.
Затем к результату применяется соответствующая логическая операция'.

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


Кроме того, если не указывать явно план, соглашаясь на предложенный при отладке запроса план
оптимизатора IB, не может-ли с течением времени (ростом БД) IB поменять данный план.

Valk, sod@dn.farlep.net

--------------------------------------------------------------------------------------------------
ПРИВОЖУ СТАТИСТИКУ ПО ОБРАБОТКЕ ЗАПРОСОВ:

SELECT T.YEARMONTH
FROM lKart T ,BaseLKart B
WHERE ((T.YEARMONTH>='200101') and (T.YEARMONTH<='200101'))
and(B.LSCHET=T.LSCHET)

Current memory = 1006592
Delta memory = -25600
Max memory = 1165408
Elapsed time= 5.77 sec
Buffers = 256
Reads = 2237
Writes 0
Fetches = 52232
----------------------------------------------------------
SELECT T.YEARMONTH
FROM lKart T ,BaseLKart B
WHERE ((T.YEARMONTH>='200101') and (T.YEARMONTH<='200101')and (T.YEARMONTH='200101'))
and(B.LSCHET=T.LSCHET)

Current memory = 1015808
Delta memory = 6144
Max memory = 1165408
Elapsed time= 5.77 sec
Buffers = 256
Reads = 2393
Writes 0
Fetches = 52302
----------------------------------------------------------
SELECT T.YEARMONTH
FROM lKart T ,BaseLKart B
WHERE ((T.YEARMONTH>='200101') and (T.YEARMONTH<='200101'))
and(B.LSCHET=T.LSCHET)
PLAN JOIN (T INDEX (RDB$PRIMARY49),B INDEX (RDB$PRIMARY47))

Current memory = 1003520
Delta memory = -3072
Max memory = 1165408
Elapsed time= 5.76 sec
Buffers = 256
Reads = 2297
Writes 0
Fetches = 52180
----------------------------------------------------------
SELECT T.YEARMONTH
FROM lKart T ,BaseLKart B
WHERE ((T.YEARMONTH>='200101') OR (T.YEARMONTH<='200101'))
and(B.LSCHET=T.LSCHET)

Current memory = 1032192
Delta memory = -1024
Max memory = 1165408
Elapsed time= 92.88 sec
Buffers = 256
Reads = 2280
Writes 0
Fetches = 2440629
---------------------------------------------------------
SELECT T.YEARMONTH
FROM lKart T ,BaseLKart B
WHERE ((T.YEARMONTH>='200101') or (T.YEARMONTH<='200101'))
and(B.LSCHET=T.LSCHET)
PLAN JOIN (T INDEX (RDB$PRIMARY49),B INDEX (RDB$PRIMARY47))

Current memory = 1009664
Delta memory = 6144
Max memory = 1165408
Elapsed time= 5.77 sec
Buffers = 256
Reads = 2297
Writes 0
Fetches = 52257
---------------------------------------------------------


mailto:sod@dn.farlep.net
...
Рейтинг: 0 / 0
1 сообщений из 1, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Что касается планирования
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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