Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Оптимизация времени выполнения скрипта / 24 сообщений из 24, страница 1 из 1
16.06.2017, 15:38
    #39473224
PavelBardRu
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
Столкнулся с проблемой значительного увеличения времени работы запроса при связывании двух простых подзапросов.
Каждый из них работает с таблицами примерно по миллиону записей и выдаёт несколько десятков строк и 5-6 полей, при этом длится менее минуты.
Когда соединяю их через left join, время работы такого объединённого скрипта возрастает до часа!
Конструкция такая:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select t1.a, t1.b, t1.c, t2.d from (
select a, b, c from 
....
) t1
left join (
select a, b, d from
...
) t2 on t1.a=t2.a and t1.b=t2.b


Сервер Firebird 2.5.7, работаю через IBExpert версия 2016.11.7.2
Как можно убыстрить процесс?
...
Рейтинг: 0 / 0
16.06.2017, 16:32
    #39473267
KreatorXXI
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
PavelBardRu,

Из примера трудно понять чего к чему.
Посмотри в IBExpert'е закладку "Анализ производительности". Скорее всего при left join идёт перемножение 1лям на 1лям.
...
Рейтинг: 0 / 0
16.06.2017, 17:58
    #39473351
PavelBardRu
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
KreatorXXI, я недавно работаю с FireBird'ом, возможно, проблемы от этого.
Раньше я в таких случаях запихивал результаты подзапросов во временные таблицы, а потом их джойнил. Если результаты подзапросов были маленькие (как сейчас у меня, 60 записей), то сджойнивание их дополнительного времени практически не занимало. Время счета равнялось сумме времён подзапросов.
То, что "перемножаются" миллионы записей, я подозреваю, но возникает вопрос: можно ли объяснить FireBird'у, что надо джойнить уже результаты подзапросов, не прокручивая полные таблицы?
Вот сейчас замерил. Два подзапроса.
Первый 3 колонки 87 строк Execute time = 6s 172ms
Второй 4 колонки 74 записи Execute time = 3s 906ms
Джойню - Execute time = 3m 42s 62ms
...
Рейтинг: 0 / 0
16.06.2017, 18:02
    #39473354
Dimitry Sibiryakov
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
PavelBardRuможно ли объяснить FireBird'у, что надо джойнить уже результаты подзапросов, не
прокручивая полные таблицы?

С левым соединением - нет.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
17.06.2017, 15:19
    #39473607
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
PavelBardRu,

firebird пока не умеет делать внешние соединения с использованием алгоритмов hash/merge. На внутренних соединениях в 2.5 будет использован алгоритм соединения merge, в 3.0 - hash join. Поэтому такие соединения будут делаться относительно быстро.
Возможно 4.0 будет уметь делать внешние соединения с использованием hash join.
...
Рейтинг: 0 / 0
17.06.2017, 18:21
    #39473645
afgm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
PavelBardRu,

Если данных из двух подзапросов на несколько десятков записей, то "убивание" внешних условий должно облегчить ситуацию.

Код: sql
1.
2.
...
) t2 on t1.a+0=t2.a+0 and t1.b+0=t2.b+0
...
Рейтинг: 0 / 0
19.06.2017, 10:24
    #39473970
WildSery
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
afgm,

Чё это вдруг?
...
Рейтинг: 0 / 0
19.06.2017, 10:29
    #39473976
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
afgm,

не должно, а может и то далеко не всегда, причём только для join, а не left join. Это не правило, а скорее исключение когда hash/merge join работает лучше чем nested loop с использованием индексов
...
Рейтинг: 0 / 0
19.06.2017, 12:08
    #39474049
WildSery
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
Симонов Денис,

Чтобы MERGE сработал, ещё сортировка нужна, скорее всего.
...
Рейтинг: 0 / 0
19.06.2017, 12:17
    #39474057
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
WildSery,

конечно нужна, вот только есть оптимизатор выберет алгоритм MERGE JOIN, то сортировку он сам воткнёт не зависисмо от того отсортированы ли данные по необходимым полям соединения или нет.

Ну и сортировка "десятков строк" это не дорого. Опять же надо пробовать, как я уже сказал принудительный merge/hash это скорее исключение чем правило. Когда нет возможность использования индексов для соединения он и так будет выбран, но не для left join. Надеюсь в 4.0 это поправят (про outer join).
...
Рейтинг: 0 / 0
19.06.2017, 13:03
    #39474088
WildSery
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
Симонов Денис,

У меня почему-то никогда не получалось "в обратную сторону".
Когда выполняешь все условия, и записи выбираются в порядке соединения (дополнительно сортировкой или в порядке индекса), тогда MERGE подхватывается.
А вот наоборот - чтобы сервер сам добавил сортировку, мне как-то не попадалось.
...
Рейтинг: 0 / 0
19.06.2017, 13:11
    #39474095
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
WildSery,

ну так ты не отключал использование индексов. Просто попробуй

Код: sql
1.
2.
3.
select count(*)
from T1
join T2 on T1.F1+0 = T2.F2+0



вот на моей базе примерчик на 2.5

Код: sql
1.
2.
3.
4.
5.
SELECT
    COUNT(*)
FROM
    FARM
    JOIN OWNERSHIP ON OWNERSHIP.CODE_OWNERSHIP+0 = FARM.CODE_OWNERSHIP+0



план
Код: plaintext
PLAN MERGE (SORT (FARM NATURAL), SORT (OWNERSHIP NATURAL))
...
Рейтинг: 0 / 0
19.06.2017, 13:21
    #39474103
afgm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
WildSeryafgm,

Чё это вдруг?
Есть подозрение, что условия джойна объединяются с внутренними, из-за этого тормоза (могу ошибаться, т.к. работаю и с 3 и 4 версией, там проброс изменился). "Материализовать" и уже потом перемножением соединить записи не должно быть долго, с учётом их небольшого количества.
...
Рейтинг: 0 / 0
19.06.2017, 13:29
    #39474108
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
afgm,

в 3.0 merge join заменён на hash join. В остальном почти всё так же.
...
Рейтинг: 0 / 0
19.06.2017, 13:41
    #39474112
WildSery
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
afgm,

Так в том-то и дело, что это всё до 4-ки не сработает.
...
Рейтинг: 0 / 0
19.06.2017, 13:51
    #39474116
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
WildSery, afgm

в оптимизаторе 4.0 по сравнению с 3.0 пока ни чего не менялось
...
Рейтинг: 0 / 0
19.06.2017, 14:04
    #39474130
WildSery
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
Симонов Денис,

Так я и не утверждаю, что в 4 точно будет :) Я надеюсь!
...
Рейтинг: 0 / 0
19.06.2017, 15:46
    #39474190
afgm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
WildSeryТак в том-то и дело, что это всё до 4-ки не сработает.
Чёйта?
2 запроса по минуте
выдают не сколько десятков (пусть сотен записей) и 6 полей (сделаем побольше).
итого 2 минуты на формирование поздапросов. Далее неэффективным пребирающим left_join-ом объединяем.
И тут вдруг час. С какого?
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
select count(*) from rdb$types
-- 228

with A as (
  select t1.rdb$type_name as type_name,
    --поля для объёма
    t1.RDB$TYPE,
    t1.RDB$DESCRIPTION,
    t1.RDB$SYSTEM_FLAG,
    'text string text string text string text string text string text string text string text string' as txt1,
    'text string text string text string text string text string text string text string text string' as txt2,
    'text string text string text string text string text string text string text string text string' as txt3,
    'text string text string text string text string text string text string text string text string' as txt4,
    'text string text string text string text string text string text string text string text string' as txt5,
    'text string text string text string text string text string text string text string text string' as txt6,
    'text string text string text string text string text string text string text string text string' as txt7,
    'text string text string text string text string text string text string text string text string' as txt8
   from rdb$types t1
)
select count(*) from A A1
left join A A2 on A1.type_name||'' = A2.type_name||''
-- PLAN JOIN (A1 T1 NATURAL, A2 T1 NATURAL)
-- Execute time = 62ms
...
Рейтинг: 0 / 0
19.06.2017, 15:46
    #39474191
afgm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
Симонов Денисв 3.0 merge join заменён на hash join. В остальном почти всё так же.
Ещё проброс условий внутрь представлений.
...
Рейтинг: 0 / 0
19.06.2017, 15:55
    #39474207
WildSery
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
afgm,

Я не понял, что ты хотел сказать. И к чему этот странный пример.
...
Рейтинг: 0 / 0
19.06.2017, 16:02
    #39474220
Симонов Денис
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
afgm,

попробовал. Твоё условие A1.type_name||'' = A2.type_name||'' скорости не добавило, как я и ожидал
...
Рейтинг: 0 / 0
19.06.2017, 17:49
    #39474328
afgm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
WildSeryafgm,

Я не понял, что ты хотел сказать. И к чему этот странный пример.
Я хотел сказать что неэффективный левый джойна на плевом объеме все равно должен отработать за вменяемое время.
...
Рейтинг: 0 / 0
19.06.2017, 17:51
    #39474331
afgm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
Симонов Денисafgm,

попробовал. Твоё условие A1.type_name||'' = A2.type_name||'' скорости не добавило, как я и ожидал
Так оно должно было замедлить.
...
Рейтинг: 0 / 0
20.06.2017, 09:11
    #39474577
WildSery
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Оптимизация времени выполнения скрипта
afgm,

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


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