Вот рекорд с OR без union — 0,046 сек или 46 миллисекунд
select
t1.id
from tx1 t1
left join tx1 t2 on t1.x1=t2.x1 and t1.id!=t2.id
left join tx1 t3 on t1.x2=t3.x2 and t1.id!=t3.id
where
t3.x2 = t1.x2 or t2.x1 = t1.x1
Re[4]: mssql сильно тормозит OR - нет, OR никак не мешает! 0.046 сек!
Здравствуйте, paradok, Вы писали:
P>Вот рекорд с OR без union — 0,046 сек или 46 миллисекунд
P>select P> t1.id P>from tx1 t1 P> left join tx1 t2 on t1.x1=t2.x1 and t1.id!=t2.id P> left join tx1 t3 on t1.x2=t3.x2 and t1.id!=t3.id P>where P> t3.x2 = t1.x2 or t2.x1 = t1.x1
В реальных задачах ещё надо ещё join-ить к t2/t3 и там опять ветвление будет
Re[5]: mssql сильно тормозит OR - нет, OR никак не мешает! 0.046 сек!
Здравствуйте, tnikolai, Вы писали:
T>Здравствуйте, paradok, Вы писали:
P>>Вот рекорд с OR без union — 0,046 сек или 46 миллисекунд
P>>select P>> t1.id P>>from tx1 t1 P>> left join tx1 t2 on t1.x1=t2.x1 and t1.id!=t2.id P>> left join tx1 t3 on t1.x2=t3.x2 and t1.id!=t3.id P>>where P>> t3.x2 = t1.x2 or t2.x1 = t1.x1
T>В реальных задачах ещё надо ещё join-ить к t2/t3 и там опять ветвление будет
давай реальный пример где у тебя опять ветвится-тормозится!
— подумаем, но пока видитcя этот подход мега универcальный и позволяет победить любое кол-во OR
Здравствуйте, gyraboo, Вы писали:
T>>inner join tbl1 on(a=b OR c=d) G>Тоже сталкивался с тормозами mysql по многим пунктам. Перешел для своих проектов на Постгрес, уже лет 10 как — не нарадуюсь и скорости, и функционалу. Переходи на постгрес))
Совет правильный, но два пункта:
1) в топике mssql, а не mysql. Поборет ли Постгря МС в общем случае — это вопрос;
2) постгря себя ведёт для подобного запроса так же "тупо", как и mssql.
Сам недавно на Постгре столкнулся с подобным, нашёл обходной путь через UNION. Гордился собой, т.к. не знал, что это общая проблема
Здравствуйте, Rhino, Вы писали:
R>2) постгря себя ведёт для подобного запроса так же "тупо", как и mssql.
R>Сам недавно на Постгре столкнулся с подобным, нашёл обходной путь через UNION. Гордился собой, т.к. не знал, что это общая проблема
Ну так это не потому что оптимизатор тупой, а просто оптимизация дизъюнкции в общем виде не так проста и требует статического анализа условий на взаимоисключаемость. Грубо говоря, есть у тебя кортеж, на нем вычисляется A or B, на выходе этот кортеж будет 0 или 1 раз (в зависимости от истинности предиката). А если ты это перепишешь в union, где слева будет этот кортеж с А, а справа он же с B, то на выходе он будет 2 раза если оба условия истинны. Т.е. меняется семантика запроса, могут появиться дубликаты. В частных случаях оптимизатор может понять, когда такое преобразование валидно, а в общем надо или оставлять все как есть, либо переписывать в union с вычитанием того же отношения с условием A & B (это плохо масштабируется если условией через OR не два, а много).
Здравствуйте, kl, Вы писали: kl>Ну так это не потому что оптимизатор тупой, а просто оптимизация дизъюнкции в общем виде не так проста и требует статического анализа условий на взаимоисключаемость. Грубо говоря, есть у тебя кортеж, на нем вычисляется A or B, на выходе этот кортеж будет 0 или 1 раз (в зависимости от истинности предиката). А если ты это перепишешь в union, где слева будет этот кортеж с А, а справа он же с B, то на выходе он будет 2 раза если оба условия истинны. Т.е. меняется семантика запроса, могут появиться дубликаты. В частных случаях оптимизатор может понять, когда такое преобразование валидно, а в общем надо или оставлять все как есть, либо переписывать в union с вычитанием того же отношения с условием A & B (это плохо масштабируется если условией через OR не два, а много).
Вроде как union устраняет дубликаты, поэтому переписывание на union формально можно делать без анализа пересекаемости условий.
ТС приводил пример именно с union, а не с union all.
Впрочем, это всего лишь означает, что union all будет ещё быстрее. А корректность его зависит от взаимосвязи между (a=b) и (c=d).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Вроде как union устраняет дубликаты, поэтому переписывание на union формально можно делать без анализа пересекаемости условий. S>ТС приводил пример именно с union, а не с union all.
А, прошу прощения, забыл об этой разнице!
S>Впрочем, это всего лишь означает, что union all будет ещё быстрее. А корректность его зависит от взаимосвязи между (a=b) и (c=d).
Ага. Устранение дубликатов — штука недешевая (если входные потоки не отсортированы по одному ключу).
Здравствуйте, kl, Вы писали:
kl>Здравствуйте, Sinclair, Вы писали:
S>>Вроде как union устраняет дубликаты, поэтому переписывание на union формально можно делать без анализа пересекаемости условий. S>>ТС приводил пример именно с union, а не с union all.
kl>А, прошу прощения, забыл об этой разнице!
Кстати, в этом случае все равно могут измениться результаты т.к. union может убрать дубликаты, которые взялись не из-за пересекаемости условий, а из самого джойна (или базовых таблиц). А union all — добавить дубликаты. В общем, непростая эта тема, оптимизация дизъюнкций общего вида.
Самый парадоксальный вариант ! — по идее должен работать страшно медленно,
но на ms-sql server 2019 работает очень быстро — почти как с UNION
при этом OR используется!
select * from tx1
where
tx1.x1 in (select t1.x1 from tx1 t1 where t1.id != tx1.id)
or
tx1.x2 in (select t2.x2 from tx1 t2 where t2.id != tx1.id)