Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Обход Natural / 21 сообщений из 21, страница 1 из 1
23.12.2003, 15:33
    #32361002
hyh
hyh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
Код: 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
23.12.2003, 15:37
    #32361012
Roman Ignatiev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
Что-то у тебя странное, во where поле NUM указано, а в индексе ID, естественно, не подходит
...
Рейтинг: 0 / 0
23.12.2003, 15:53
    #32361044
Gold
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
Имей ввиду два момента:
1) В плане IB не всегда показывает все индексы, которые он использует
2) Натурал не всегда плохо. Иногда он эффективней чем индексная выборка.
Я вобще придерживаюсь мнения что планы руками лучше не писать.
...
Рейтинг: 0 / 0
23.12.2003, 15:56
    #32361051
hyh
hyh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
Сорри, Очепятка
Код: plaintext
1.
Create index id_ind on ORD(num)

Не хочет использовать и упрямо пишет Natural, что естественно не убыстряет
работу и без того тормозящей процедуры.
...
Рейтинг: 0 / 0
23.12.2003, 15:59
    #32361055
hyh
hyh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
Я вобще придерживаюсь мнения что планы руками лучше не писать. Я на самом деле тоже)
Просто пытаюсь разобраться в причинах тормозов.
Да и всё таки - в явном то виде почему он не хочет его использовать?
...
Рейтинг: 0 / 0
23.12.2003, 16:01
    #32361057
Roman Ignatiev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
Считает, что с ним будет медленнее. НА выбор плана влияет многое, и порядок выражений во where, и количество записей в таблицах, и селективность индекса... А natural здесь скорее всего из-за distinct. Попробуй group by O2.ID вместо него
...
Рейтинг: 0 / 0
23.12.2003, 17:25
    #32361240
hyh
hyh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
Вот объясните мне почему это
Код: 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
23.12.2003, 17:38
    #32361258
Gold
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
Откудова мы знаем почему. Посмотри статистику в эксперте по индексированным и неиндексированным чтениям. Возможно 1-й запрос в несколько раз ограничивает количество обрабатываемых записей - вот оно и быстрее. В любом случае смотри статистику.
...
Рейтинг: 0 / 0
23.12.2003, 18:29
    #32361332
hyh
hyh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
Естественно смотрел) И если бы она проясняла, не спрашивал бы...
Нет неиндексированных и по ~190тысяч индексированных чтений из каждой из
4х табличек для первого(быстрого) и ~1.300.000 к fulfildoc, ~1.400.000 к
ORdITEMSTATE - индексированные и ~59000 к ORD неиндексированных
для второго.
Почему так я без понятия) - 2й запрос работает с меньшим числом табличек и выбирает меньше данных))
...
Рейтинг: 0 / 0
23.12.2003, 18:58
    #32361357
Gold
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
Фух, что за человек. Ну сделай же ты индекс по ORD.NUM и по ORDITEMSTATE.ORDNUM !!!
...
Рейтинг: 0 / 0
23.12.2003, 19:00
    #32361358
Gold
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
А, так это ещё и под ИБ7 все крутиться Ну тогда не удивляйся если странные планы будешь получать
...
Рейтинг: 0 / 0
23.12.2003, 19:22
    #32361385
hyh
hyh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
Этой базе лет эдак уже несколько
Есть все там индексы :/
Под IB7.0 всё
...
Рейтинг: 0 / 0
24.12.2003, 08:33
    #32361557
Zmeishe
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
Код: plaintext
1.
AND (F.INPDATE >= :D1)
AND (F.INPDATE <= :D2)
Вот поэтому и натурал.

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

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

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

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

Если тебе действительно интересно плановое хозяйство,
то ходи сюда krista.ru, очень полезно...:)
...
Рейтинг: 0 / 0
24.12.2003, 10:26
    #32361670
Zmeishe
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
Это только одна из причин, из моего опыта.
Другие возможные причины:
- имеет значение порядок полей в индексе. Я как-то игрался с порядком полей и нашёл комбинацию, при которой Natural изчез.
- имеет значение разбить один запрос по нескольким таблицам на несколько запросов через ХП for select do ... for select do Например в запросе три таблицы. Если все известные мне способы, избавиться от Natural, исчерпаны, я разбиваю на один запрос из двух таблиц и один запрос из одной таблицы.
...
Рейтинг: 0 / 0
24.12.2003, 12:15
    #32361881
dimitr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
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
24.12.2003, 13:28
    #32361989
hyh
hyh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
На
Код: 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
24.12.2003, 13:47
    #32362026
hyh
hyh
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
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
24.12.2003, 13:57
    #32362064
dimitr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Обход Natural
2hyh

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

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


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


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