Re[13]: Подскажите алгоритм быстрого left join (ms t-sql)
От: BlackEric http://black-eric.lj.ru
Дата: 19.05.22 11:06
Оценка: 18 (1)
Здравствуйте, paradok, Вы писали:

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


BE>>Можно сделать join с помощью linq. Не знаю как будет по скорости.

BE>>Join two tables using LINQ Query and order based two parameters

P>попробую!, но скорее всего оно все равно транслируетсz в sql left join и отправляется на сервер.


Это уже зависит от того над чем вы проводите операции.
Вытягивайте данные в DataTable и с ними уже работайте. Или какие-то коллекции подберите.
https://github.com/BlackEric001
Re[11]: Подскажите алгоритм быстрого left join (ms t-sql)
От: vaa  
Дата: 19.05.22 12:20
Оценка: 18 (1)
Здравствуйте, paradok, Вы писали:

P>я думал кто-то подскажет как вообще на уровне кода на C# делается аналог лефт джойна на многомерных массивах чисел

https://docs.microsoft.com/en-us/dotnet/csharp/linq/perform-left-outer-joins

ЗЫ. то эксел, то сишарп, на шарпе конечно проще
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: Подскажите алгоритм быстрого left join (ms t-sql)
От: _ABC_  
Дата: 19.05.22 12:53
Оценка: 18 (1) +1
Здравствуйте, paradok, Вы писали:

P>Из sql studio запрос left join по id выполняется за 3..5 сек, отлично! (с компа разраба, с повыш. правами)

P>из хранимой процедуры — 5..10 минут! Кошмар ! (с компов обычных юзеров)
P>код строго один и тот же!
Код разный по описанию. Из студии — запрос, из экселя — хранимка, в которую запрос обернут. Это два разных запроса с двумя разными планами выполнения.
Если хранимку из студии запустить — результат какой будет?

P>Кажется не хватает юзерам выполняющему вызов хранимой процедуры каких-о прав и ресурсов (памяти например)...

С точки зрения SQL Server нет разделения производительности по правам и ресурсам.

Немного гадания на кофейной гуще в попытке помочь.

С точки зрения SQL Server разница в производительности может быть обусловлена:
  • разными планами у хранимки и прямого запроса (попробуйте запустить хранимку с рекомпиляцией https://www.brentozar.com/archive/2013/12/recompile-hints-and-execution-plan-caching/)
  • разными параметрами сессии. https://docs.microsoft.com/en-us/sql/t-sql/statements/set-statements-transact-sql?view=sql-server-ver15. Попробуйте поиграться, выставив для экселя в хранимке set nocount on; set arithabort on;. Arithabort по опыту сильно может влиять на производительность хранимки, при этом по умолчанию в студии он включен, а в сессиях клиентов выключен.

    С учётом, что простой вывод содержимого таблиц в Эксель быстрый, другие потенциальные причины типа пропускной способности сети и прочего я бы не рассматривал, пока не рассмотрены более вероятные причины.

    P>ВОПРОС:

    P>Подскажите какие алгоритмы применяются для быстрого left join
    В зависимости от предположительного количества данных SQL Server будет применять либо loop join, либо merge join, либо hash match.
    SQL Server сам решит, что эффективнее.

    Каждый из них эффективен в разных сценариях. Например, loop join эффективен при малом количестве записей в условной правой таблице. И если хранимка была скомпилирована когда был эффективен loop join, а с тех пор количество записей существенно возросло, время выполнения хранимки вырастет по экспоненте.

    Поэтому тебе нужно для начала убедиться, что у хранимки эффективный план выполнения.
    Для начала, запусти из Студии её, посмотри время выполнения. Если большое, рекомпилируй её.
    Добавь команды set.
    Если вопрос решится, посмотри на автообновление статистики, чтобы вручную хранимку не перекомпилировать.

    P>и можно ли их как-то имплементировать их (на ms t-sql) с меньшими требованиями по памяти,

    P>но хотя бы укладываться в 10 сек, а не в 5 минут?
    Без плана запроса сказать невозможно.

    P>P.S. что-то смутно промелькнула мысль про слияние таблиц и сортировку по id с последующими траспозицией ... очень смутно ... не?

    SQL Server с этим всем справится намного эффективнее, если вы ему мешать не будете.
  • "Потерял дар речи за зря"(с).
    Re[7]: Подскажите алгоритм быстрого left join (ms t-sql)
    От: _ABC_  
    Дата: 19.05.22 12:59
    Оценка: 22 (2)
    Здравствуйте, paradok, Вы писали:

    P>нет доступа, это высоко нагруженная система с тысячами юзеров

    P>- админ жесток, ничего не дает.
    Этот админ — DBA или эникейщик? Если второе, то какое он имеет отношение к администрированию СУБД?
    А если первое, то почему не помогает с решением проблемы? Это его прямая обязанность.

    P>да и какой там план ?!

    А вот это и интересно. Actual execution plan тебе даст достаточный объём информации о том, как имеено SQL Server выбирает эти данные, даже в случае простого запроса.
    Тем более, что простые запросы хранимки и селекта куда проще сравнить и найти разницу.

    P>это полный реальный запрос.

    Ну и как выглядит план для запроса и для хранимки?
    "Потерял дар речи за зря"(с).
    Re: Подскажите алгоритм быстрого left join (ms t-sql)
    От: klopodav  
    Дата: 19.05.22 13:07
    Оценка: 18 (1)
    P>ВОПРОС:
    P>Подскажите какие алгоритмы применяются для быстрого left join

    Вообще-то на уровне СУБД уже реализованиы разные алгоритмы джойна, и планировщик запросов выбирает по его мнению наиболее подходящий. Но иногда может выбрать и неоптимально — поэтому план запроса было бы неплохо посмотреть.
    Но зато выбором алгоритма можно управлять вручную с помощью хинтов. Для MSSQL — см., например, здесь. Можешь попробовать сравнить запросы с разными хинтами — будет ли разница в быстродействии
    Re[2]: Подскажите алгоритм быстрого left join (ms t-sql)
    От: _ABC_  
    Дата: 19.05.22 13:38
    Оценка: 3 (1)
    Здравствуйте, klopodav, Вы писали:

    K>Но зато выбором алгоритма можно управлять вручную с помощью хинтов. Для MSSQL — см., например, здесь. Можешь попробовать сравнить запросы с разными хинтами — будет ли разница в быстродействии

    Не надо хинты совать бездумно.

    Для начала приведи базу в порядок, убедись, что необходимые индексы созданы и поддерживаются в порядке, что статистика своевременно обновляется и репрезентативна, что хранимки написаны грамотно, а уж потом для редких случаев можно хинты указать. И пристально за ними следить, т.к. они станут неэффективны через некоторое время, если база сильно изменится.
    "Потерял дар речи за зря"(с).
    Re[8]: Подскажите алгоритм быстрого left join (ms t-sql)
    От: paradok  
    Дата: 19.05.22 13:45
    Оценка:
    Здравствуйте, _ABC_, Вы писали:


    _AB>А если первое, то почему не помогает с решением проблемы? Это его прямая обязанность.


    к сожалению его прямая обязанность — другая. Сохранность базы, безопасность, безотказность, ровная нагрузка без перегрузов, управление доступом.
    1 тыс. юзеров онлайн.

    _AB>Тем более, что простые запросы хранимки и селекта куда проще сравнить и найти разницу.

    написал заявку в нашу тикет систему тех поддержки, пока доступа к этому нет.

    продолжая изучать вижу, что торможение стартует когда из запроса получается более 10 тыс. строк.
    думаю все же лимит на память для ограниченных юзеров на хранимые процедуры выставлен в sql сервере.
    Re[2]: Подскажите алгоритм быстрого left join (ms t-sql)
    От: paradok  
    Дата: 19.05.22 14:00
    Оценка:
    Здравствуйте, _ABC_, Вы писали:

    план запроса пока нет — доступ у меня закрыт. Придется без него.

    _AB>Каждый из них эффективен в разных сценариях. Например, loop join эффективен при малом количестве записей в условной правой таблице. И если хранимка была скомпилирована когда был эффективен loop join, а с тех пор количество записей существенно возросло, время выполнения хранимки вырастет по экспоненте.


    да, тестирование в процедуре показало, что кажется есть два порога.
    1) до 10 строк на выходе — имхо мелено, 10 сек
    2) до 10 тыс. строк на выходе, умеренно — 14 сек
    3) более 10 тыс. — замедление, при 100 тыс. уже 5 мин.
    Re[3]: Подскажите алгоритм быстрого left join (ms t-sql)
    От: klopodav  
    Дата: 19.05.22 14:03
    Оценка: 6 (1)
    K>>Но зато выбором алгоритма можно управлять вручную с помощью хинтов. Для MSSQL — см., например, здесь. Можешь попробовать сравнить запросы с разными хинтами — будет ли разница в быстродействии
    _AB>Не надо хинты совать бездумно.

    _AB>Для начала приведи базу в порядок, убедись, что необходимые индексы созданы и поддерживаются в порядке, что статистика своевременно обновляется и репрезентативна, что хранимки написаны грамотно, а уж потом для редких случаев можно хинты указать. И пристально за ними следить, т.к. они станут неэффективны через некоторое время, если база сильно изменится.


    Как минимум их можно использовать в процессе отладки для проверки гипотезы "тормоза из-за того, что выбран не тот алгоритм джойна". При том, что как ТС указал — получить доступ к плану запроса у него проблематично.
    А так — да, для реальной эксплуатации базы они нужны редко, лучше обходиться другими средствами.
    Re[3]: Подскажите алгоритм быстрого left join (ms t-sql)
    От: paradok  
    Дата: 19.05.22 14:06
    Оценка:
    Здравствуйте, _ABC_, Вы писали:


    _AB>Для начала приведи базу в порядок, убедись, что необходимые индексы созданы и поддерживаются в порядке, что статистика своевременно обновляется и репрезентативна, что хранимки написаны грамотно, а уж потом для редких случаев можно хинты указать. И пристально за ними следить, т.к. они станут неэффективны через некоторое время, если база сильно изменится.


    индексов нет. 2 таблицы по 200..300к, обе обновляются 1 раз в 3 мин.
    код в хранимке максимально простой
    select * from table1 left join table2 on table1.id = table2.id

    Думаете надо пытаться пересоздавать индексы при каждом вызове процедуры?
    Отредактировано 19.05.2022 14:07 paradok . Предыдущая версия .
    Re[4]: Подскажите алгоритм быстрого left join (ms t-sql)
    От: klopodav  
    Дата: 19.05.22 14:15
    Оценка:
    P>индексов нет. 2 таблицы по 200..300к, обе обновляются 1 раз в 3 мин.

    Ну чисто в порядке гадания на кофейной гуще — а что понимается под "обновляется"? Там добавляются-меняются записи в небольшом количестве? Или возможна ситуация, когда таблица была почти пустая, а при очередном обновлении фигак — и добавилось 200к записей?
    Если второй вариант — тогда как раз было бы подозрение на то, что старый план запроса может стать неоптимальным.
    Re: Подскажите алгоритм быстрого left join (ms t-sql)
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 19.05.22 14:18
    Оценка: 98 (2)
    Здравствуйте, paradok, Вы писали:

    P>ПРОБЛЕМА:

    P>Из sql studio запрос left join по id выполняется за 3..5 сек, отлично! (с компа разраба, с повыш. правами)
    P>из хранимой процедуры — 5..10 минут! Кошмар ! (с компов обычных юзеров)
    P>код строго один и тот же!

    Проблема гуглится https://www.sommarskog.se/query-plan-mysteries.html

    P>Кажется не хватает юзерам выполняющему вызов хранимой процедуры каких-о прав и ресурсов (памяти например)...

    P>Изменить права нет возможности, я не сисадмин, а он ничего менять не будет, т.к. в сети под 1к компов с разыми правами "агрессивных и хитрых" юзеров
    P>и любое изменение в стабильно работающей системе чревато дырами в безопасности и проблемами с чрезмерной нагрузкой на сервера (по его словам).
    P>(дать процедуре более высокие права, чем вызывающему ее юзеру тоже нельзя — отказ от сисадмина)
    Нет, права не при чем

    P>ВОПРОС:

    P>Подскажите какие алгоритмы применяются для быстрого left join
    Минимальный cost имеет inner loop

    P>и можно ли их как-то имплементировать их (на ms t-sql) с меньшими требованиями по памяти,

    P>но хотя бы укладываться в 10 сек, а не в 5 минут?
    Как связаны память и время выполнения?

    P>P.S. что-то смутно промелькнула мысль про слияние таблиц и сортировку по id с последующими траспозицией ... очень смутно ... не?

    Не


    Объяви процедуру с опцией WITH RECOPILE и будет тебе счастье.

    PS. При чем тут раздел "алгоритмы" ?
    Re[2]: Подскажите алгоритм быстрого left join (ms t-sql)
    От: paradok  
    Дата: 19.05.22 14:27
    Оценка:
    Здравствуйте, gandjustas, Вы писали:

    G>Проблема гуглится https://www.sommarskog.se/query-plan-mysteries.html

    спасибо! плюсанул! — изучаю.

    G>Как связаны память и время выполнения?

    что будет если вся таблица не поместится в отведенную процессу оперативную память и начнется свопирование на диск в виртуальную память?

    G>Объяви процедуру с опцией WITH RECOPILE и будет тебе счастье.

    попробовал, ничего не изменилось.

    G>PS. При чем тут раздел "алгоритмы" ?

    ну типа хотел полностью свой left join имплементировать

    подумал возможно дело не в памяти, а в каких-то лимитах на юзера по скорости обмена по сети... или по файловой системе... если такое вообще возможно...
    попробовал одну из таблиц копировать в базу к которой у меня почти админские права и которая на другом тестовом сервере — стало быстрее, но время отработки прыгает...нестабильно...
    но для других юзеров не прокатывает, медленно, у которых обычные права к этой этой базе. в идеале надо бы процедуру запускать только с моим правами, но пока админ не дал добро.
    так что... пока думаю...
    Отредактировано 19.05.2022 14:35 paradok . Предыдущая версия .
    Re[3]: Подскажите алгоритм быстрого left join (ms t-sql)
    От: gandjustas Россия http://blog.gandjustas.ru/
    Дата: 19.05.22 14:48
    Оценка: 18 (1)
    Здравствуйте, paradok, Вы писали:

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


    G>>Проблема гуглится https://www.sommarskog.se/query-plan-mysteries.html

    P>спасибо! плюсанул! — изучаю.

    G>>Как связаны память и время выполнения?

    P>что будет если вся таблица не поместится в отведенную процессу оперативную память и начнется свопирование на диск в виртуальную память?
    Какая таблица?
    Для Inner loop не требуется всю таблицу в память загружать.

    G>>Объяви процедуру с опцией WITH RECOPILE и будет тебе счастье.

    P>попробовал, ничего не изменилось.
    тогда читай по ссылке и проверяй
    А вообще рассуждать о быстродействии запросов можно только глядя на планы

    G>>PS. При чем тут раздел "алгоритмы" ?

    P>ну типа хотел полностью свой left join имплементировать
    Зачем? MS SQL ты не обгонишь, так как он использует индексы и статистику чтобы не читать данные с диска, которые не нужны для выполнения запросов. Только когда все данные в памяти ты можешь написать свое нечто по типу hash join, но в этом смысла нет.

    P>подумал возможно дело не в памяти, а в каких-то лимитах на юзера по скорости обмена по сети... или по файловой системе... если такое вообще возможно...

    Нет, проблема в плане запроса

    P>попробовал одну из таблиц копировать в базу к которой у меня почти админские права и которая на другом тестовом сервере — стало быстрее, но время отработки прыгает...нестабильно...

    P>но для других юзеров не прокатывает, медленно, у которых обычные права к этой этой базе. в идеале надо бы процедуру запускать только с моим правами, но пока админ не дал добро.
    P>так что... пока думаю...
    Смотри план запроса
    Re[4]: Подскажите алгоритм быстрого left join (ms t-sql)
    От: _ABC_  
    Дата: 19.05.22 21:33
    Оценка: +1
    Здравствуйте, klopodav, Вы писали:

    K>Как минимум их можно использовать в процессе отладки для проверки гипотезы "тормоза из-за того, что выбран не тот алгоритм джойна". При том, что как ТС указал — получить доступ к плану запроса у него проблематично.

    Какая проблема нажать Ctrl+M в студии и запустить выполнение хранимки?
    "Потерял дар речи за зря"(с).
    Re[4]: Подскажите алгоритм быстрого left join (ms t-sql)
    От: _ABC_  
    Дата: 19.05.22 21:34
    Оценка: 3 (1)
    Здравствуйте, paradok, Вы писали:

    P>Думаете надо пытаться пересоздавать индексы при каждом вызове процедуры?

    Нет, этого точно не надо делать.
    "Потерял дар речи за зря"(с).
    Re[3]: Подскажите алгоритм быстрого left join (ms t-sql)
    От: vaa  
    Дата: 20.05.22 01:44
    Оценка: 3 (1)
    Здравствуйте, paradok, Вы писали:

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


    P>план запроса пока нет — доступ у меня закрыт. Придется без него.


    _AB>>Каждый из них эффективен в разных сценариях. Например, loop join эффективен при малом количестве записей в условной правой таблице. И если хранимка была скомпилирована когда был эффективен loop join, а с тех пор количество записей существенно возросло, время выполнения хранимки вырастет по экспоненте.


    P>да, тестирование в процедуре показало, что кажется есть два порога.

    P>1) до 10 строк на выходе — имхо мелено, 10 сек
    P>2) до 10 тыс. строк на выходе, умеренно — 14 сек
    P>3) более 10 тыс. — замедление, при 100 тыс. уже 5 мин.

    Покажите код на C#, 100 тыс для sql это мелочи, если только у вас не +100500 блоб-полей в таблицах(кстати, посмотрите размер таблиц).
    Чуйка что в коде проблема. в датагрид не выводится при запросе случайно?
    про код поподробней. что это плагин к экселю? или exe с гуем?
    ☭ ✊ В мире нет ничего, кроме движущейся материи.
    Re: Подскажите алгоритм быстрого left join (ms t-sql)
    От: paradok  
    Дата: 21.06.22 08:59
    Оценка:
    Спасибо коллег за ответы!

    проблему на 3+ удалось решить
    копированием 2-х таблиц в базу где у меня почти все права и выполнения left join в ней хранимой процедурой в ней же.
    Права на выполнение процедуры и чтению данных с этой базы были выданы всем нужным юзерам.

    То есть решил чисто огранизационными методами...
    но осадочек остался... буду еще копать в направлении планов выполнения
    Re: Подскажите алгоритм быстрого left join (ms t-sql)
    От: EugeneIvanov Земля http://e-ivanov.ru/portfolio/
    Дата: 27.06.22 07:53
    Оценка:
    4 секунды — это очень, очень долго

    подобные запросы за 4 мс должны выполняться.

    проставьте индексы
    Re[3]: Подскажите алгоритм быстрого left join (ms t-sql)
    От: Tom Россия http://www.RSDN.ru
    Дата: 02.01.23 18:47
    Оценка:
    Здравствуйте, paradok, Вы писали:

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



    BE>>Ну и без самого запроса что-то подсказать


    P>select * from table1 left join table2 on table1.id = table2.id


    Индексы по полям table1.id и table2.id — есть?
    Народная мудрось
    всем все никому ничего(с).
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.