powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Сложный запрос
13 сообщений из 38, страница 2 из 2
Сложный запрос
    #39463715
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockсчитаешь чушью (как ты и написал), что left легче inner?
что значит "легче"? "тяжесть" выполнения запроса зависит от плана. left/right приводят к принудительному порядку объединения таблиц. А у inner или неявных join сервер может сам определить порядок объединения таблиц.

Так что да - про "легче" это если не чушь, то собственная терминология, которая далека от реальности. Сравнивать принудительный порядок и произвольный? Да еще учитывая, что планы могут оказаться одинаковыми.
...
Рейтинг: 0 / 0
Сложный запрос
    #39463721
Фотография kdv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockЕсли есть возможность, лучше заменять их на left/right [outer] join'ы - они работают "в один проход" при чем "с нужной стороны", в отличие от inner.
например, вот это чушь. То есть, inner работает "в два прохода", что-ли? Одинаково они работают, просто генерируют разные планы (а иногда и одинаковые). Через left/right ты просто можешь принудительно "задать план", который "работает быстрее".

p.s. про "работает быстрее" - зависит от того, выбирается несколько первых записей, или fetch all. Один и тот же массив записей может выбираться разное время, в зависимости от плана запроса (методов доступа).

рекомендую перечитать
http://www.ibase.ru/dataaccesspaths/

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

Ты план запроса видел? Вполне возможно надо просто где-то индекс создать, может +0, а может и вовсе запрос переписать. А ты свои left join без причины пытаешься воткнуть.

То что starting with не может использовать индекс тоже чушь.

И то что left "легче" inner я действительно считаю чушью.

З.Ы. Тут никто не пытается тебя оскорбить или ущемить твоё самолюбие, но ты действительно не сечёшь фишку. Почитай приведённую kdv статью.
...
Рейтинг: 0 / 0
Сложный запрос
    #39463742
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
insert into TAKE_SL (ID_TAKE, ID_SL, ID_SCHET)
                 select :id_take, sl.ID, sl.id_r_schet
                 from r_sl sl
                 join r_schet s on s.id = sl.id_r_schet and s.status_fin = 1  -- принят к оплате
                 join s_type_schet st on st.id = s.id_type_schet and st.r_typ = 1 and st.typ_omp = 3 and st.id not in (46,48,13,58,59)
                 join r_pacient p on p.id = sl.id_r_pacient and age_person(p.dr,sl.dt_end) < 65

                 join r_pacient p1 on p1.npolis = p.npolis
                 join r_sl sl1 on  sl1.id_r_pacient = p1.id and sl1.id <> sl.id
                                   and sl1.nomlpu = sl.nomlpu and sl1.usl_ok = 3 and sl1.pr_opl = 1
                                   and substring(sl1.ds1 from 1 for 3) = substring(sl.ds1 from 1 for 3)
                                   and sl1.prvs = sl.prvs
                                   and sl1.cel not in ('2','90','91','92','94','11','61','62','63')
                                   and sl1.code_mes1 not in ('RT20','RT21','RT22','RT23','RT24','RT41')
                                   and abs(datediff(day, sl1.dt_end, sl.dt_end)) <16
                                   and iif ((sl.dt_end < sl1.dt_end and sl.type_pos = 2 and sl1.type_pos = 1)
                                             or (sl.dt_end > sl1.dt_end and sl.type_pos = 1 and sl1.type_pos = 2),0,1) = 1
                 where sl.nomlpu =:nomlpu
                       and sl.usl_ok = 3
                       and sl.pr_opl = 1
                       and substring(sl.ds1 from 1 for 1) not in ('C','S','O','Z','Q')
                       and substring(sl.ds1 from 1 for 3) not in ('J00','J01','J02','J03','J04','J05','J06','J07','J08','B18','J35',
                                                                  'N11','N18','N19','N20','T14','B00','B01','B02','B02','B03','B04',
                                                                  'B05','M01','M02','M03','M04','M05','M06','M07','M08','M09','M10',
                                                                  'L50','N80','N81','N82','N83','N84','N85','N86','N87','N88','N89',
                                                                  'N90','N91','N92','N93','N94','N95','N96','N97','N98')
                       and sl.prvs not in(28,263,126,91,258,115,80,17,1,206)
                       and sl.cel not in ('2','90','91','92','94','11','61','62','63')
                       and sl.code_mes1 not in ('RT20','RT21','RT22','RT23','RT24','RT41')
                       and (not exists(select 1 from xml_foms_sl fe where fe.id_sl = sl.id))
                       and (not exists (select first 1 1 from r_oe_sl oesl where oesl.id_sl = sl.id))
                       and (not exists (select first 1 1 from fines f where f.id_sl = sl.id and f.cod_type_exp > 0))
                       and (not exists (select first 1 1 from take_sl tsl_t where tsl_t.id_sl = sl.id and tsl_t.id_take  <> :id_take ))

                       and (not exists(select 1 from xml_foms_sl fe1 where fe1.id_sl = sl1.id))
                       and (not exists (select first 1 1 from r_oe_sl oesl1 where oesl1.id_sl = sl1.id))
                       and (not exists (select first 1 1 from fines f1 where f1.id_sl = sl1.id and f1.cod_type_exp > 0))
                       and (not exists (select first 1 1 from take_sl tsl_t1 where tsl_t1.id_sl = sl1.id and tsl_t1.id_take <> :id_take));


На данный момент вот такой запрос, он отрабатывает быстрее чем с exists, но совсем неправильно
Например
один человек сходил 3 раза в поликлинику, 28.03 - sl.id = 1, 10.04 -sl.id = 2, 13.04 - sl.id = 3. Запрос отрабатывает таким образом, что в результате находятся пары 1 - 2, 2 - 3. То есть вместо трех отбираются четыре 1,2,2,3. Это можно как-то исправить?
...
Рейтинг: 0 / 0
Сложный запрос
    #39463747
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кареглазая_зая,

версия сервера какая?
...
Рейтинг: 0 / 0
Сложный запрос
    #39463766
Симонов Денис, 2.1.
...
Рейтинг: 0 / 0
Сложный запрос
    #39463771
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kdvнапример, вот это чушь. То есть, inner работает "в два прохода", что-ли? Одинаково они работают, просто генерируют разные планы (а иногда и одинаковые). Через left/right ты просто можешь принудительно "задать план", который "работает быстрее".
Как минимум я отключаю работу оптимизитора (для этого момента), а так же страхуюсь от его возможных ошибок.
Кстати, сейчас провел некоторые тесты своих запросов 14-летней давности на тройке, поменял LEFT на INNER. И, да, план и быстродействие оказались одинаковыми. В то время такого щастья не было, отсюда и привычка "заранее отсекать неверный план".
Вот честно, мне сейчас очень сложно будет перестроиться и НЕ писать LEFT там, где я уверен, что он будет оптимален.
...
Рейтинг: 0 / 0
Сложный запрос
    #39463781
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

не ну 14 лет назад оптимизатор был так себе. Сейчас намного лучше.
...
Рейтинг: 0 / 0
Сложный запрос
    #39463783
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов ДенисТы план запроса видел? Вполне возможно надо просто где-то индекс создать, может +0, а может и вовсе запрос переписать. А ты свои left join без причины пытаешься воткнуть.
Как оказалось, версия 2.1, а на ней оптимизатор еще не тот, что сейчас. План, конечно, смотреть надо.

Симонов ДенисТо что starting with не может использовать индекс тоже чушь.

Ты цитируешь то, что я НЕ писал. Я писал:
" not starting with"

а так же
"индекс сомневаюсь, что получится использовать".

Симонов ДенисИ то что left "легче" inner я действительно считаю чушью.
Возможно сейчас, когда оптимизатор стал достаточно хорош, это и так. А раньше план мог измениться в "неправильную сторону" просто при накоплении данных в базу, и приходилось его "направлять", и поэтому лучше было сразу так делать.

Симонов ДенисЗ.Ы. Тут никто не пытается тебя оскорбить или ущемить твоё самолюбие
Это я понимаю прекрасно, тут все на нервах постоянно)
...
Рейтинг: 0 / 0
Сложный запрос
    #39463790
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockСимонов ДенисТо что starting with не может использовать индекс тоже чушь.

Ты цитируешь то, что я НЕ писал. Я писал:
" not starting with"

а так же
"индекс сомневаюсь, что получится использовать".

Уже и не сомневаюсь. Проверил только что на 3.0.1, который у меня в продакшене:
Код: sql
1.
2.
3.
SELECT * FROM COMMANDS C
WHERE NOT C.COMMAND_ID STARTING WITH 'O'
--WHERE C.COMMAND_ID STARTING WITH 'O'


Планы такие:
PLAN (C NATURAL)
и если NOT убрать:
PLAN (C INDEX (PK_COMMANDS))

есть PRIMARY KEY (COMMAND_ID),
COMMAND_ID CHAR(4) NOT NULL
...
Рейтинг: 0 / 0
Сложный запрос
    #39463793
Фотография Симонов Денис
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

not я проглядел, там в принципе индекс проблематично использовать
...
Рейтинг: 0 / 0
Сложный запрос
    #39463826
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кареглазая_зая,

Мда, тут уже проще выполнить в процедуре наиболее простой запрос с этими страшными условиями, отстртировав по "НомеруПолиса,Дате", и затем в цикле инсертить, если надо. Так хотя бы наглядно будет.
Другое дело, как в процедуру эти условия передавать трёхэтажные.. Их лучше в отдельной таблице хранить - как "настройки отчета".
...
Рейтинг: 0 / 0
Сложный запрос
    #39463886
WildSery
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Симонов Денисне ну 14 лет назад оптимизатор был так себе. Сейчас намного лучше."Так себе" только по сравнению с новым. Работал и ладно.
Всегда как-то хватало псевдо-хинтов, да и то нечасто.
Вот чтобы LEFT приходилось писать - это только когда с процедурой соединение, других случаев не припоминаю.
...
Рейтинг: 0 / 0
13 сообщений из 38, страница 2 из 2
Форумы / Firebird, InterBase [игнор отключен] [закрыт для гостей] / Сложный запрос
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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