Re: mssql сильно тормозит OR
От: tnikolai  
Дата: 16.09.21 22:13
Оценка:
Наконец то нашёл как

CREATE NONCLUSTERED INDEX IX_tx1 ON tx1 (x1);
CREATE NONCLUSTERED INDEX IX_tx2 ON tx1 (x2);

select * from tx1 t1 WITH (FORCESEEK)
inner join tx1 t2 on(t1.x1=t2.x1 or t1.x2=t2.x2) and t1.id!=t2.id
Re[2]: mssql сильно тормозит OR
От: Maniacal Россия  
Дата: 17.09.21 06:08
Оценка:
Здравствуйте, tnikolai, Вы писали:

T>Наконец то нашёл как


А то я уже хотел предложить воспользоваться хинтами к плану выполнения запроса
Re[3]: mssql сильно тормозит OR - нет, OR никак не мешает! 0.046 сек!
От: paradok  
Дата: 17.09.21 07:37
Оценка: 4 (1)
Вот рекорд с 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 сек!
От: tnikolai  
Дата: 17.09.21 13:41
Оценка:
Здравствуйте, 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 сек!
От: paradok  
Дата: 17.09.21 14:37
Оценка:
Здравствуйте, 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
Re[2]: mssql сильно тормозит OR
От: Rhino СССР  
Дата: 28.09.21 14:04
Оценка:
Здравствуйте, gyraboo, Вы писали:

T>>inner join tbl1 on(a=b OR c=d)

G>Тоже сталкивался с тормозами mysql по многим пунктам. Перешел для своих проектов на Постгрес, уже лет 10 как — не нарадуюсь и скорости, и функционалу. Переходи на постгрес))
Совет правильный, но два пункта:
1) в топике mssql, а не mysql. Поборет ли Постгря МС в общем случае — это вопрос;
2) постгря себя ведёт для подобного запроса так же "тупо", как и mssql.

Сам недавно на Постгре столкнулся с подобным, нашёл обходной путь через UNION. Гордился собой, т.к. не знал, что это общая проблема
... << RSDN@Home 1.0.0 alpha 5 rev. 0>>
Re[3]: mssql сильно тормозит OR
От: kl Германия http://stardog.com
Дата: 01.10.21 19:12
Оценка: 40 (2) +2
Здравствуйте, Rhino, Вы писали:

R>2) постгря себя ведёт для подобного запроса так же "тупо", как и mssql.


R>Сам недавно на Постгре столкнулся с подобным, нашёл обходной путь через UNION. Гордился собой, т.к. не знал, что это общая проблема


Ну так это не потому что оптимизатор тупой, а просто оптимизация дизъюнкции в общем виде не так проста и требует статического анализа условий на взаимоисключаемость. Грубо говоря, есть у тебя кортеж, на нем вычисляется A or B, на выходе этот кортеж будет 0 или 1 раз (в зависимости от истинности предиката). А если ты это перепишешь в union, где слева будет этот кортеж с А, а справа он же с B, то на выходе он будет 2 раза если оба условия истинны. Т.е. меняется семантика запроса, могут появиться дубликаты. В частных случаях оптимизатор может понять, когда такое преобразование валидно, а в общем надо или оставлять все как есть, либо переписывать в union с вычитанием того же отношения с условием A & B (это плохо масштабируется если условией через OR не два, а много).
no fate but what we make
Re[4]: mssql сильно тормозит OR
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.10.21 16:44
Оценка:
Здравствуйте, 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).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: mssql сильно тормозит OR
От: kl Германия http://stardog.com
Дата: 11.10.21 06:43
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Вроде как union устраняет дубликаты, поэтому переписывание на union формально можно делать без анализа пересекаемости условий.

S>ТС приводил пример именно с union, а не с union all.

А, прошу прощения, забыл об этой разнице!

S>Впрочем, это всего лишь означает, что union all будет ещё быстрее. А корректность его зависит от взаимосвязи между (a=b) и (c=d).


Ага. Устранение дубликатов — штука недешевая (если входные потоки не отсортированы по одному ключу).
no fate but what we make
Re[6]: mssql сильно тормозит OR
От: kl Германия http://stardog.com
Дата: 11.10.21 09:23
Оценка:
Здравствуйте, kl, Вы писали:

kl>Здравствуйте, Sinclair, Вы писали:


S>>Вроде как union устраняет дубликаты, поэтому переписывание на union формально можно делать без анализа пересекаемости условий.

S>>ТС приводил пример именно с union, а не с union all.

kl>А, прошу прощения, забыл об этой разнице!


Кстати, в этом случае все равно могут измениться результаты т.к. union может убрать дубликаты, которые взялись не из-за пересекаемости условий, а из самого джойна (или базовых таблиц). А union all — добавить дубликаты. В общем, непростая эта тема, оптимизация дизъюнкций общего вида.
no fate but what we make
Re: mssql сильно тормозит OR
От: paradoks  
Дата: 06.02.22 12:56
Оценка:
Самый парадоксальный вариант ! — по идее должен работать страшно медленно,
но на 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)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.