powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите с запросом
17 сообщений из 17, страница 1 из 1
Помогите с запросом
    #39842989
SHS_SHS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток.
Есть 2 таблицы (для примера): Table1 "легкая" и Table2 "очень тяжелая".
Упрощенный запрос для этих таблиц выглядит так:
Код: sql
1.
2.
3.
select t1.id, (select sum(t2.amount) from table2 t2 where t2.id_table1 = t1.id) as sum_amount
from table1 t1
where t1.....


работает достаточно быстро, но когда появляется необходимость сделать проверку по sum_amount, нужно приписывать запрос так:
Код: sql
1.
2.
3.
4.
5.
6.
select t1.id, tt.sum_amount, iif(tt.sum_amount > 1000, 1, 0)
from table1 t1
left join (select t2.id_table1, sum(t2.amount) as sum_amount
           from table2 t2
           order by t2.id) tt on tt.id_table1 = t1.id)
where t1.....


или так:
Код: sql
1.
2.
3.
4.
5.
select id, sum_amount, iif(sum_amount > 1000, 1, 0)
from
(select t1.id, (select sum(t2.amount) from table2 t2 where t2.id_table1 = t1.id) as sum_amount
from table1 t1
where t1.....)


Первый работает долго, второй - быстро. Есть еще варианты с GROUP BY, но они не всегда подходят. Написан не очень умный парсер запросов, и второй запрос распарсить и подставить что-то в него он не может. Такая же сложность для запросов с group by.
Может есть варианты для проверки суммы в первом запросе, без select в selectе и без group by? Firebird 3.0 поддерживает over, но что-то я не могу понять как его использовать в данном случае.
...
Рейтинг: 0 / 0
Помогите с запросом
    #39842991
SHS_SHS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Пардон, второй запрос:
select t1.id, tt.sum_amount, iif(tt.sum_amount > 1000, 1, 0)
from table1 t1
left join (select t2.id_table1, sum(t2.amount) as sum_amount
from table2 t2
group by t2.id_table1) tt on tt.id_table1 = t1.id)
where t1.....
...
Рейтинг: 0 / 0
Помогите с запросом
    #39842993
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SHS_SHSкогда появляется необходимость сделать проверку по sum_amount, нужно приписывать запрос так

Левый джоин тут не нужен. Order by в deived table - тоже. Наверняка точками прикрыто
что-то аналогично бессмысленное.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Помогите с запросом
    #39843001
SHS_SHS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
С order by ошибся. left остался от оригинального запрос. В where кончено же ерунда написана, как без этого :). Но с просто join работает все равно дольше, чем с select в selectе.
Код: sql
1.
2.
3.
4.
5.
6.
select t1.id, tt.sum_amount, iif(tt.sum_amount > 1000, 1, 0)
from table1 t1
join (select t2.id_table1, sum(t2.amount) as sum_amount
      from table2 t2
      group by t2.id_table1) tt on tt.id_table1 = t1.id
where t1.....


Для данного запроса подсчет сумм идет для всей Table2, а уже потом объединение?
...
Рейтинг: 0 / 0
Помогите с запросом
    #39843005
Фотография Старый плюшевый мишка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry SibiryakovSHS_SHSкогда появляется необходимость сделать проверку по sum_amount, нужно приписывать запрос так

Левый джоин тут не нужен. Order by в deived table - тоже. Наверняка точками прикрыто
что-то аналогично бессмысленное.


А ведь я лет 15 назад говорил господам фичереквестерам, что если что-то может быть использовано через анус, то только так оно и будет использоваться.
...
Рейтинг: 0 / 0
Помогите с запросом
    #39843015
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SHS_SHS,

в принципе при наличии индекса запрос с LEFT JOIN должен работать достаточно шустро. Приведи полный запрос 2 и его план
...
Рейтинг: 0 / 0
Помогите с запросом
    #39843029
SHS_SHS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: sql
1.
2.
3.
select t1.id, (select sum(t2.amount) from table2 t2 where t2.id_table1 = t1.id) as sum_amount
from table1 t1
where t1.field1 = '1234'


-- 250ms
PLAN (T2 INDEX (TABLE2))
PLAN (T1 NATURAL)


Код: sql
1.
2.
3.
4.
5.
6.
select t1.id, tt.sum_amount, iif(tt.sum_amount > 1000, 1, 0)
from table1 t1
join (select t2.id_table1, sum(t2.amount) as sum_amount
      from table2 t2
      group by t2.id_table1) tt on tt.id_table1 = t1.id
where t1.field1 = '1234'


-- 2s 138ms
PLAN JOIN (TT T2 ORDER TABLE2, T1 INDEX (TABLE1))
...
Рейтинг: 0 / 0
Помогите с запросом
    #39843039
SHS_SHS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Тут проблема, что самописный парсер не понимает select в selecte, и плохо работает с group by. Есть ли какой-то вариант (как выше сказали "через одно место") сделать что-то быстро в запросе, вроде этого:
Код: sql
1.
2.
3.
select t1.id, (select sum(t2.amount) from table2 t2 where t2.id_table1 = t1.id) as sum_amount, iif(sum_amount > 1000, 1, 0)
from table1 t1
where t1.field = '1234'


или смирится со скоростью выполнения второго запроса.... или дописывать парсер. Сейчас парсер понимает все поля (какими бы кривыми не были), все объединения таблиц (подзапросов) через joinы. С group by работает, но с group by можно динамически добавить в запрос поля, а хотелось бы и таблицы (этого нет).
...
Рейтинг: 0 / 0
Помогите с запросом
    #39843042
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SHS_SHS-- 250ms
PLAN (T2 INDEX (TABLE2))
PLAN (T1 NATURAL)

Здесь ты явно забыл нажать "Fetch All".
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Помогите с запросом
    #39843044
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SHS_SHS,

а вот так:
Код: sql
1.
2.
3.
4.
5.
select t1.id, sum(t2.amount), iif(sum(t2.amount) > 1000, 1, 0)
from table1 t1
       inner join table2 t2 on t2.id_table1=t1.id
where t1.....
group by 1
...
Рейтинг: 0 / 0
Помогите с запросом
    #39843045
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SHS_SHS,

чёт планы у тебя какие-то кривоватые мягко говоря или ты индексы по уродливому назвал. Лучше уж explain план. Да ну ладно время не такое уж и большое на самом деле.
Сообщи архитектуру и размер страничного кэша.

И вообще твоём случае скорее всего вот такого запроса вполне хватит

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
select 
  t2.id_table1 as id, 
  sum(t2.amount) as sum_amount, 
  iif(sum(t2.amount)  > 1000, 1, 0)
from table1 t1
join table2 t2 on  t2.id_table1 = t1.id
where t1.field1 = '1234'
group by t2.id_table1
...
Рейтинг: 0 / 0
Помогите с запросом
    #39843055
SHS_SHS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Симонов ДенисSHS_SHS,

в принципе при наличии индекса запрос с LEFT JOIN должен работать достаточно шустро. Приведи полный запрос 2 и его план

Кстати да, с LEFT JOIN в упрощенной форме запроса работает реально быстрее:
Код: sql
1.
2.
3.
4.
5.
6.
select t1.id, tt.sum_amount, iif(tt.sum_amount > 1000, 1, 0)
from table1 t1
left join (select t2.id_table1, sum(t2.amount) as sum_amount
           from table2 t2
           group by t2.id_table1) tt on tt.id_table1 = t1.id
where t1.field1 = '1234'



--250ms
PLAN JOIN (T1 NATURAL, TT T2 ORDER TABLE2)

В оригинале запроса для этой связки стоит тоже left join, поменял для другого объединения на left join (хотя там связь без null) и переставил объединение ниже этой - все летает. Похоже оптимизатор наконец-то понял мою ересь мой запрос.
...
Рейтинг: 0 / 0
Помогите с запросом
    #39843062
SHS_SHS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Планы криповаты, т.к. за столько лет без ошибок писать так и не научился.

-- 250ms
PLAN (T2 INDEX (FK_TABLE2_1))
PLAN (T1 NATURAL)

-- 2s 138ms
PLAN JOIN (TT T2 ORDER FK_TABLE2_1, T1 INDEX (PK_TABLE1_1))

-- 250ms
PLAN JOIN (T1 NATURAL, TT T2 ORDER FK_TABLE2_1)

FetchAll не нажимал, т.к. там результат в 15-20 строк. Но на всякий проверил, результаты почти такие же.
...
Рейтинг: 0 / 0
Помогите с запросом
    #39843064
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SHS_SHS,

ИМХО, левый джойн - костыль. Не пробовал мой или последний запрос Дениса? Вроде всё прозрачно.
...
Рейтинг: 0 / 0
Помогите с запросом
    #39843071
SHS_SHS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В этих запросах group by. Я знаю как написать запрос с ним. Если в двух словах описать почему нельзя, то: Есть "костяк" запроса, который выводит отчет. Но вдруг пользователю нужны еще поля, он в специальной форме выбирает их. Парсер проходит по запросу и подставляет в него поля, и если нужно подключает таблицы. А использование group by "ломает" это. Но все равно спасибо.
...
Рейтинг: 0 / 0
Помогите с запросом
    #39843075
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KreatorXXI,

я бы не сказал что костыль, но у автора явно не тот случай когда именно LEFT JOIN нужен к производной таблице или CTE
...
Рейтинг: 0 / 0
Помогите с запросом
    #39843094
KreatorXXI
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SHS_SHS,

понял. У нас тоже есть что-то подобное. Но и есть возможность сделать настраиваемый group by. Конструкция вложенных селектов (не "select from select", а именно вложенных) легче для конструктора запросов. Но, сами видите, провал по производительности очень часто обеспечен.
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Помогите с запросом
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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