Долго выполняется запрос

Access Violation, некорректное выполнение запросов или вызовов API, ошибки утилит командной строки, в общем все, что вам мешает работать

Модераторы: kdv, dimitr

Ответить
Olegas
Сообщения: 36
Зарегистрирован: 14 сен 2005, 07:57

Долго выполняется запрос

Сообщение Olegas » 20 окт 2006, 11:48

Запрос работает с сервером Firebird 1.0.0.338 под Win2k сервером.

Код: Выделить всё

select d1.topic d1_1,
       dat1.context d1,
       dat2.topic d2,
       dat3.topic d3,
       dat4.topic d4,
       t.ddate,
       d_s.*
 from mydocs t join mydata d on t.dockey = d.dockey
                 join datalist d_s on d.recno = d_s.recno
                 left join spr1 dat1 on dat1.recno = d.key_d1
                 left join spr1 dat2 on dat2.recno = d.key_d2
                 left join spr1 dat3 on dat3.recno = d.key_d3
                 left join spr1 dat4 on dat4.recno = d.key_c1
 where  t.doccode = 2
      and t.ddate between :DateStart and :DateEnd
Запрос выполняется 45с.
Если убрать все left, на выполнение запроса уходит 2с.
Анализ производительности показывает, что по какой-то причине резко возрастает количество неиндексированных обращений к таблице datalist. С индексом все в порядке.Если убрать left, неиндексированных обращений вообще нет.

Как поднять производительность запроса? Баг ли это сервера?

Вот план в первом случае:

План
PLAN SORT (JOIN (JOIN (JOIN (JOIN (JOIN (D_S NATURAL,D INDEX (RDB$PRIMARY21),T INDEX (RDB$PRIMARY22,mydocs_ddate,mydocs_DOCCODE,mydocs_ddate_D)),dat1 INDEX (RDB$PRIMARY6)),dat2 INDEX (RDB$PRIMARY6)),dat3 INDEX (RDB$PRIMARY6)),dat4 INDEX (RDB$PRIMARY6)))

Адаптированный план
PLAN SORT (JOIN (JOIN (JOIN (JOIN (JOIN (D_S NATURAL,D INDEX (PK_mydata),T INDEX (PK_mydocs,mydocs_ddate,mydocs_DOCCODE,mydocs_ddate_D)),dat1 INDEX (PK_SPR1)),dat2 INDEX (PK_SPR1)),dat3 INDEX (PK_SPR1)),dat4 INDEX (PK_SPR1)))

Вот план во втором случае:

План
PLAN SORT (JOIN (T INDEX (mydocs_ddate,mydocs_DOCCODE,mydocs_ddate_D),D INDEX (RDB$FOREIGN23),dat4 INDEX (RDB$PRIMARY6),D_S INDEX (RDB$PRIMARY88),dat1 INDEX (RDB$PRIMARY6),dat2 INDEX (RDB$PRIMARY6),dat3 INDEX (RDB$PRIMARY6)))

Адаптированный план
PLAN SORT (JOIN (T INDEX (mydocs_ddate,mydocs_DOCCODE,mydocs_ddate_D),D INDEX (FK_mydata),dat4 INDEX (PK_SPR1),D_S INDEX (PK_datalist),dat1 INDEX (PK_SPR1),dat2 INDEX (PK_SPR1),dat3 INDEX (PK_SPR1)))

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Re: Долго выполняется запрос

Сообщение WildSery » 20 окт 2006, 13:05

Olegas писал(а):

Код: Выделить всё

T INDEX (RDB$PRIMARY22,mydocs_ddate,mydocs_DOCCODE,mydocs_ddate_D)
Это что за фигня? Почему столько индексов навалено?

Во-вторых, LEFT не будет тебе объединять по индексам, прому что RTFM.

В-третьих, где таблица с алиасом d1 ?

В-четвёртых, если у тебя по одному полю выбираются, ну так сделай подзапросами, типа

Код: Выделить всё

select d1.topic d1_1, /* !? */
       (select context from spr where recno = d.key_d1) d1,
       (select topic from spr where recno = d.key_d2) d2,
       (select topic from spr where recno = d.key_d3) d3,
       (select topic from spr where recno = d.key_d4) d4,
       t.ddate,
       d_s.*
  from mydocs t
       join mydata d on (t.dockey = d.dockey+0)
       join datalist d_s on (d.recno+0 = d_s.recno)
  where t.doccode+0=2 and t.ddate between :DateStart and :DateEnd
И в-пятых, обновляй версию сервера.

kdv
Forum Admin
Сообщения: 6595
Зарегистрирован: 25 окт 2004, 18:07

Сообщение kdv » 20 окт 2006, 21:27

Запрос работает с сервером Firebird 1.0.0.338
Олег, вы очумели, извините за выражение? Вам мало того что надо СРОЧНО менять версию, если не можете на FB 1.5, то хотя бы на FB 1.02/1.03, но и вообще на 338-ом билде НЕЛЬЗЯ РАБОТАТЬ. Там есть нехороший баг с rdb$formats, т.е. можно получить битую базу.
Как поднять производительность запроса? Баг ли это сервера?
обычно в тормозах запроса виноват его написавший. но опять же, обычно, он всегда думает что виноват кто-то другой.

зачем вам столько left join? Вы уверены? Скорее, мне кажется, что запрос из какого то "автоматизированного построителя".
Прочитайте
www.ibase.ru/devinfo/joins.htm

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Re: Долго выполняется запрос

Сообщение dimitr » 21 окт 2006, 12:34

WildSery писал(а):LEFT не будет тебе объединять по индексам, прому что RTFM
это в каком FM такое написано?

dimitr
Разработчик Firebird
Сообщения: 888
Зарегистрирован: 26 окт 2004, 16:20

Re: Долго выполняется запрос

Сообщение dimitr » 21 окт 2006, 12:36

Olegas писал(а):Как поднять производительность запроса?
попробуй так:

Код: Выделить всё

select d1.topic d1_1,
       dat1.context d1,
       dat2.topic d2,
       dat3.topic d3,
       dat4.topic d4,
       t.ddate,
       d_s.*
 from mydocs t join mydata d on t.dockey = d.dockey and t.doccode = 2
      and t.ddate between :DateStart and :DateEnd
                 join datalist d_s on d.recno = d_s.recno
                 left join spr1 dat1 on dat1.recno = d.key_d1
                 left join spr1 dat2 on dat2.recno = d.key_d2
                 left join spr1 dat3 on dat3.recno = d.key_d3
                 left join spr1 dat4 on dat4.recno = d.key_c1
Olegas писал(а):Баг ли это сервера?
если совет выше помог - то да, баг. Исправлен в FB2. Иначе - ХЗ.

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Re: Долго выполняется запрос

Сообщение WildSery » 23 окт 2006, 11:11

dimitr писал(а):это в каком FM такое написано?
Ни в каком, конечно. :oops:
Это я чего-то пятничное ляпнул. Мысль была о другом, хотел написать что-нибудь типа не получишь ты так, как при INNER JOIN, а получилось ...

Ответить