powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Обход Natural
21 сообщений из 21, страница 1 из 1
Обход Natural
    #32361002
hyh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
SELECT DISTINCT O2.ID
FROM ORDITEMSTATE O1,
 FULFILDOC F, ORD O2
WHERE
 (F.NUM = O1.FFDOCNUM)
 AND (F.INPDATE >= :D1)
 AND (F.INPDATE <= :D2)
 AND (O2.NUM = O1.ORDNUM)

Код: plaintext
PLAN SORT (JOIN (O2 NATURAL,O1 INDEX (XPKORDITEMSTATE),F INDEX (RDB$PRIMARY46)))

Natural
Код: plaintext
Create index id_ind on ORD(ID)

Создаем индекс. делаем коммит, вновь вводим запрос и опять имеем Natural.
Пишем
Код: plaintext
1.
 AND (O2.NUM = O1.ORDNUM)
PLAN SORT (JOIN (O2 INDEX(id_ind),O1 INDEX (XPKORDITEMSTATE),F INDEX (RDB$PRIMARY46)))
Реакция - 'index cannot be used in the specified plan
.
index ID_IND cannot be used in the specified plan.
'
Почему?
...
Рейтинг: 0 / 0
Обход Natural
    #32361012
Roman Ignatiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что-то у тебя странное, во where поле NUM указано, а в индексе ID, естественно, не подходит
...
Рейтинг: 0 / 0
Обход Natural
    #32361044
Gold
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Имей ввиду два момента:
1) В плане IB не всегда показывает все индексы, которые он использует
2) Натурал не всегда плохо. Иногда он эффективней чем индексная выборка.
Я вобще придерживаюсь мнения что планы руками лучше не писать.
...
Рейтинг: 0 / 0
Обход Natural
    #32361051
hyh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Сорри, Очепятка
Код: plaintext
1.
Create index id_ind on ORD(num)

Не хочет использовать и упрямо пишет Natural, что естественно не убыстряет
работу и без того тормозящей процедуры.
...
Рейтинг: 0 / 0
Обход Natural
    #32361055
hyh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я вобще придерживаюсь мнения что планы руками лучше не писать. Я на самом деле тоже)
Просто пытаюсь разобраться в причинах тормозов.
Да и всё таки - в явном то виде почему он не хочет его использовать?
...
Рейтинг: 0 / 0
Обход Natural
    #32361057
Roman Ignatiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Считает, что с ним будет медленнее. НА выбор плана влияет многое, и порядок выражений во where, и количество записей в таблицах, и селективность индекса... А natural здесь скорее всего из-за distinct. Попробуй group by O2.ID вместо него
...
Рейтинг: 0 / 0
Обход Natural
    #32361240
hyh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот объясните мне почему это
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
SELECT DISTINCT O2.ID, SUM(O.TOTAL),
 COUNT(DISTINCT O2.CLNUM)
FROM ORDITEM O, ORDITEMSTATE O1,
 FULFILDOC F, ORD O2
WHERE
(O1.ORDNUM = O.ORDNUM)
 AND (O1.ITEMNUM = O.ITEMNUM)
 AND (O1.FFDOCTYPE = 'A')
 AND (O1.STATECODE IN ('0','1'))
 AND (F.NUM = O1.FFDOCNUM)
 AND (F.INPDATE >= '10.10.2003')
 AND (F.INPDATE <= '15.10.2003')
 AND (O2.NUM = O.ORDNUM)
GROUP BY O2.ID
ORDER BY O2.ID,  2 ,  3 

выполняется за 1.15сек, a

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
SELECT DISTINCT O2.ID
FROM ORDITEMSTATE O1,
 FULFILDOC F, ORD O2
WHERE
 (F.NUM = O1.FFDOCNUM)
 AND (F.INPDATE >= '10.10.2003')
 AND (F.INPDATE <= '15.10.2003')
 AND (O2.NUM = O1.ORDNUM)
не меньше 2х минут при различных комбинациях джойнов(условий во Where)
При замене distinct на group by, Natural исчезает, но выполняется при этом оно за 4 минуты :\
...
Рейтинг: 0 / 0
Обход Natural
    #32361258
Gold
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Откудова мы знаем почему. Посмотри статистику в эксперте по индексированным и неиндексированным чтениям. Возможно 1-й запрос в несколько раз ограничивает количество обрабатываемых записей - вот оно и быстрее. В любом случае смотри статистику.
...
Рейтинг: 0 / 0
Обход Natural
    #32361332
hyh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Естественно смотрел) И если бы она проясняла, не спрашивал бы...
Нет неиндексированных и по ~190тысяч индексированных чтений из каждой из
4х табличек для первого(быстрого) и ~1.300.000 к fulfildoc, ~1.400.000 к
ORdITEMSTATE - индексированные и ~59000 к ORD неиндексированных
для второго.
Почему так я без понятия) - 2й запрос работает с меньшим числом табличек и выбирает меньше данных))
...
Рейтинг: 0 / 0
Обход Natural
    #32361357
Gold
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фух, что за человек. Ну сделай же ты индекс по ORD.NUM и по ORDITEMSTATE.ORDNUM !!!
...
Рейтинг: 0 / 0
Обход Natural
    #32361358
Gold
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А, так это ещё и под ИБ7 все крутиться Ну тогда не удивляйся если странные планы будешь получать
...
Рейтинг: 0 / 0
Обход Natural
    #32361385
hyh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Этой базе лет эдак уже несколько
Есть все там индексы :/
Под IB7.0 всё
...
Рейтинг: 0 / 0
Обход Natural
    #32361557
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
AND (F.INPDATE >= :D1)
AND (F.INPDATE <= :D2)
Вот поэтому и натурал.

Сделай так:
Код: plaintext
AND (F.INPDATE between :D1 AND :D2)

IB5 и IB6 очень чутко реагировали на это. IB7 я ещё не проверял.
...
Рейтинг: 0 / 0
Обход Natural
    #32361641
Фотография Dnico
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe

Там Natural не из-за AND (F.INPDATE >= :D1) AND (F.INPDATE <= :D2). У меня тоже одна из 3-х всегда Natural ...

Best regards,
Dnico.
...
Рейтинг: 0 / 0
Обход Natural
    #32361653
Фотография Johnmen
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>hyh

Если тебе действительно интересно плановое хозяйство,
то ходи сюда krista.ru, очень полезно...:)
...
Рейтинг: 0 / 0
Обход Natural
    #32361670
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это только одна из причин, из моего опыта.
Другие возможные причины:
- имеет значение порядок полей в индексе. Я как-то игрался с порядком полей и нашёл комбинацию, при которой Natural изчез.
- имеет значение разбить один запрос по нескольким таблицам на несколько запросов через ХП for select do ... for select do Например в запросе три таблицы. Если все известные мне способы, избавиться от Natural, исчерпаны, я разбиваю на один запрос из двух таблиц и один запрос из одной таблицы.
...
Рейтинг: 0 / 0
Обход Natural
    #32361881
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1. Тормоза точно из-за NATURAL, а не из-за SORT? Убери DISTINCT и сравни время выполнения.
2. Ты подсовываешь серверу неправильный явный план. Если не разбираешся в выполнении джойнов сервером, то за их ручную оптимизацию лучше не берись.
3. Сервер сможет использовать индексы для всех потоков джойна только в одном случае - если (а) есть индексы по FULFILDOC.INPDATE и ORDITEMSTATE.FFDOCNUM и (б) таблица FULFILDOC стоит первой в порядке соединения. Т.е. явный план должен быть примерно такой (имена индексов условны):

Код: plaintext
PLAN SORT (JOIN (F INDEX (IDX_INPDATE), O1 INDEX (IDX_FFDOCNUM), O2 INDEX (IDX_NUM)))

4. Даже в случае вышеуказанного плана выполнение может быть медленее. Как тут уже правильно сказали, NATURAL - это зачастую не есть зло. Если у тебя в таблице ORD записей немного, а индекс по FULFILDOC.INPDATE имеет плохую селективность, то оптимизатор тебе выдал наилучший план из возможных.
5. Какую производительность дает следующий запрос:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
SELECT
  DISTINCT O2.ID
FROM
  FULFILDOC F
    LEFT JOIN ORDITEMSTATE O1 ON (F.NUM = O1.FFDOCNUM)
    LEFT JOIN ORD O2 ON (O1.ORDNUM = O2.NUM)
WHERE
  (F.INPDATE >= :D1) AND (F.INPDATE <= :D2)

???
6. Если ничего из вышесказанного не помогает, то IB7 must die, однозначно ;-)
...
Рейтинг: 0 / 0
Обход Natural
    #32361989
hyh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
SELECT
  DISTINCT O2.ID
FROM
  FULFILDOC F
    LEFT JOIN ORDITEMSTATE O1 ON (F.NUM = O1.FFDOCNUM)
    LEFT JOIN ORD O2 ON (O1.ORDNUM = O2.NUM)
WHERE
  (F.INPDATE >= :D1) AND (F.INPDATE <= :D2)
Создает план
Код: plaintext
PLAN SORT (JOIN (JOIN (F NATURAL,O1 INDEX (XIF150ORDITEMSTATE)),O2 INDEX (RDB$PRIMARY56)))

И выполняется на 3 с небольшим секунды ))
По 33 тысячи запросов идет к ORD, ORDITEMSTATE - индексированных,
почти ~12.5 тысяч - неиндексированных к FULFILDOC
...
Рейтинг: 0 / 0
Обход Natural
    #32362026
hyh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe,
Тут ведь нужны ID для филиалов у которых есть документы нужного типа в
нужном промежутке времени
Если, например, выбрать все у которых есть нужного типа, а потом все у кого
нужной даты, то попадут те, у кого нет нужного типа в этом временном промежутке,
зато есть документы других типов))
то есть так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
SELECT DISTINCT O2.ID
FROM ORDITEMSTATE O1,
 FULFILDOC F, ORD O2
WHERE
 (F.NUM = O1.FFDOCNUM)
 AND (F.INPDATE >= :D1)
 AND (F.INPDATE <= :D2)
 AND (O2.NUM = O1.ORDNUM)
into :IDD
do begin
 ID=NULL;
 SELECT O2.ID
 FROM ORDITEMSTATE O1, ORD O2
 WHERE
 (((O1.FFDOCTYPE = 'A') AND (O1.STATECODE IN ('0','1')))
 OR
 (O1.FFDOCTYPE IN ('L','R')) )
 AND (O2.NUM = O1.ORDNUM) AND (O2.ID = :IDD)
 into :ID;

 IF (ID IS NOT NULL) THEN BEGIN
неправильно.
На самом деле разбивать я пробовал разбивать по уникальному вобщем-то ORDNUMу(текст уже потер), но вис этот вариант с неменьшим энтузиазмом)
То есть разбивка 1) может быть корректна только с виду 2) К сожалению не всегда помогает

Johnmen,
Почитаем) Жаль только оно 2х летней давности - видимо когда разбирались с ИБ написали)
...
Рейтинг: 0 / 0
Обход Natural
    #32362064
dimitr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2hyh

Т.е. индекса по INPDATE у тебя нет, получается? Тогда можешь дописать к своему первоначальному запросу план:

Код: plaintext
PLAN SORT (JOIN (F NATURAL, O1 INDEX (XIF150ORDITEMSTATE), O2 INDEX (RDB$PRIMARY56)))


и радоваться тем же 3 секундам.
...
Рейтинг: 0 / 0
Обход Natural
    #32362086
hyh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
INPDATE добавляется же часто ..
Ведь индексы при каждом inserte не перестраиваются?
dimitr, да, спасибо, сейчас попробую реадизовать всё в похожем виде)
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Обход Natural
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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