ОПИСАНИЕ:
Есть две таблицы, без индексов, по 200..300к записей, таблицы частично обновляются 1 раз 2-3 мин.
делаем left join по id (вы выводим всю результирующую таблицу в csv или excel)
id в обеих таблицах чуток не уникальный, порядка 1..2% дубликатов по id (но не всех полей строк) — принципиально не устранимо (!)
(id не уникальны, но есть метки времени, которые тоже не уникальны, но не коррелированы с id и не коррелированы между таблицами, по ним left join не сделать)
ПРОБЛЕМА:
Из sql studio запрос left join по id выполняется за 3..5 сек, отлично! (с компа разраба, с повыш. правами)
из хранимой процедуры — 5..10 минут! Кошмар ! (с компов обычных юзеров)
код строго один и тот же!
Кажется не хватает юзерам выполняющему вызов хранимой процедуры каких-о прав и ресурсов (памяти например)...
Изменить права нет возможности, я не сисадмин, а он ничего менять не будет, т.к. в сети под 1к компов с разыми правами "агрессивных и хитрых" юзеров
и любое изменение в стабильно работающей системе чревато дырами в безопасности и проблемами с чрезмерной нагрузкой на сервера (по его словам).
(дать процедуре более высокие права, чем вызывающему ее юзеру тоже нельзя — отказ от сисадмина)
ВОПРОС: Подскажите какие алгоритмы применяются для быстрого left join
и можно ли их как-то имплементировать их (на ms t-sql) с меньшими требованиями по памяти,
но хотя бы укладываться в 10 сек, а не в 5 минут?
P.S. что-то смутно промелькнула мысль про слияние таблиц и сортировку по id с последующими траспозицией ... очень смутно ... не?
Здравствуйте, paradok, Вы писали:
P>ОПИСАНИЕ: P>Есть две таблицы, без индексов, по 200..300к записей, таблицы частично обновляются 1 раз 2-3 мин. P>делаем left join по id (вы выводим всю результирующую таблицу в csv или excel) P>id в обеих таблицах чуток не уникальный, порядка 1..2% дубликатов по id (но не всех полей строк) — принципиально не устранимо (!) P>(id не уникальны, но есть метки времени, которые тоже не уникальны, но не коррелированы с id и не коррелированы между таблицами, по ним left join не сделать)
P>ПРОБЛЕМА: P>Из sql studio запрос left join по id выполняется за 3..5 сек, отлично! P>из хранимой процедуры — 5..10 минут! Кошмар ! P>код строго один и тот же!
Сравнивайте планы запросов. А после этого можно будет делать выводы.
Ну и без самого запроса что-то подсказать
Здравствуйте, paradok, Вы писали:
P>ПРОБЛЕМА: P>Из sql studio запрос left join по id выполняется за 3..5 сек, отлично! P>из хранимой процедуры — 5..10 минут! Кошмар ! P>код строго один и тот же!
А где хранимка выполняется?
в студии вы фетчите первые 1000 записей, а прога клиента может все засасывать на локалку и еще потом
обрабатывать как-то хитро отсюда и дополнительные 10 минут.
включите профайлер и посмотрите есть ли действительно разница в скорости запросов.
скорее всего нет.
могу посоветовать добавить индексы на поля которые id или сделать из запроса view(они вроде бы кэшироваться умеют).
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[2]: Подскажите алгоритм быстрого left join (ms t-sql)
из excel как exec имя_процедуры
vaa>в студии вы фетчите первые 1000 записей,
там можно все 300к вывести, необязательно первые 1000
я вывожу все 300к и сохраняют в файл csv или xls
на скорость это не влияет, все равно 3..5 сек, очень быстро.
> а прога клиента может все засасывать на локалку и еще потом vaa>обрабатывать как-то хитро отсюда и дополнительные 10 минут.
нет, вся прога это exec имя_процедуры
внутри
select * from tabl1 left join tabl2 on table1.id = table2.id
vaa> могу посоветовать добавить индексы на поля которые id
попробую, но таблицы все время обновляются...
можете примерно сказать время создания индекса?
>>или сделать из запроса view(они вроде бы кэшироваться умеют).
не очень, данные все врем меняются...
Если обе таблицы по очереди вывожу отдельными хранмками тиипа select * from table1
на листы эксель — время работы — 4 сек.
И да 300 тыс. для эксель не проблема. Все очень быстро.
Я уже думаю соединить эти таблицы уже в эксель через олап — модель данных — сводная таблица — это занимает около 2-х минут, в 2 раз быстрее чем в хранимке!
Здравствуйте, paradok, Вы писали:
P>Здравствуйте, vaa, Вы писали:
vaa>>Здравствуйте, paradok, Вы писали:
P>>>проблема точно не в эксель.
vaa>>а в студии хранимка за сколько отрабатывает?
P>10 сек
P>студия на компе разраба с повыш. правами P>Тормозит на компах (логинах) обычных юзеров.
Проверяйте тогда под логином обычного юзера. Воткните логи в хранимку. Точно ли она тормозит.
Здравствуйте, paradok, Вы писали:
P>Здравствуйте, vaa, Вы писали:
vaa>>Здравствуйте, paradok, Вы писали:
P>>>проблема точно не в эксель.
vaa>>а в студии хранимка за сколько отрабатывает?
P>10 сек
P>студия на компе разраба с повыш. правами P>Тормозит на компах (логинах) обычных юзеров.
уточните, на компах или логинах?
1) создайте sql-пользователя с правами юзера и проверьте на пк разраба, аналогичным образом.
2) в студии есть Sql profiler там есть профили T-SQL запустить на базе(Фильтр по имени)
и посмотрите действительно ли он 10 минут выполняется.
просто слабо верится что права влияют так на скорость запроса. не встречал такого.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[6]: Подскажите алгоритм быстрого left join (ms t-sql)
vaa>уточните, на компах или логинах?
у разраба можно логин а можно к серверу sql и через аутентификацию виндов — работает одинаково быстро.
(но разраб не может залогиниться с юзерскго компа, как-то хитро настроено)
если под логином юзера то везде медленно.
Но именно left join на двух обновляемых таблицах
Есть еще внутри-системные таблицы с индексами и 100-миллионными записями — там left join работает быстро везде.
Ну тут гадать не надо.
Админ sql сервера сказал, что он специально все так настроил по правам групп юзеров,
и менять ничего не будет и как конкретно он это сделал секрета не расскажет.
vaa>просто слабо верится что права влияют так на скорость запроса. не встречал такого.
я тоже, но факт на лицо!
в доках ms sql сервера когда-т попадалось.. что для групп юзеров можно много чего настроить, в том числе лимиты на оперативку, лимиты на врем. табы, на врем жизни скрипта, и тд.
P>в доках ms sql сервера когда-т попадалось.. что для групп юзеров можно много чего настроить, в том числе лимиты на оперативку, лимиты на врем. табы, на врем жизни скрипта, и тд.
ну тогда это не в алгоритмы, это к начальнику — ругаться!
можно конечно и на vb хреначить, но это же не наш метод.
на крайняк может есть коннектор к локальным БД типа sqlite в память грузить и там джоинить.
или в excel прямо там же тоже что-то имеется для объедиения.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[10]: Подскажите алгоритм быстрого left join (ms t-sql)
Здравствуйте, vaa, Вы писали:
vaa>Здравствуйте, paradok, Вы писали:
P>>в доках ms sql сервера когда-т попадалось.. что для групп юзеров можно много чего настроить, в том числе лимиты на оперативку, лимиты на врем. табы, на врем жизни скрипта, и тд.
vaa>ну тогда это не в алгоритмы, это к начальнику — ругаться! vaa>можно конечно и на vb хреначить, но это же не наш метод. vaa>на крайняк может есть коннектор к локальным БД типа sqlite в память грузить и там джоинить. vaa>или в excel прямо там же тоже что-то имеется для объедиения.
в excel можно
1) функция ВПР() но она еще медленнее
2) можно через olap -> модель данных -> язык olap запросов MDX -> сводная таблица, но это для меня пока сложновато — это целый отдельный мир непохожий на sql
я думал кто-то подскажет как вообще на уровне кода на C# делается аналог лефт джойна на многомерных массивах чисел
мысль было что как-то через объединение массивов и быструю сортировку по id (на быстрых алгоритмах сортировки)
типа где-то вот так... примерно...
пусть есть два массива чисел (id)
сделать left join можно было бы
дописав второй массив в конец первому
затем сортировку по id
далее транспонирование по повторяющимся id
получаем двух мерную таблицу — аналог left join
тут нет сканирующего поиска, а только быстра сортировка — должно работать очень быстро.
Здравствуйте, paradok, Вы писали:
P>Здравствуйте, vaa, Вы писали:
vaa>>Здравствуйте, paradok, Вы писали:
P>>>в доках ms sql сервера когда-т попадалось.. что для групп юзеров можно много чего настроить, в том числе лимиты на оперативку, лимиты на врем. табы, на врем жизни скрипта, и тд.
vaa>>ну тогда это не в алгоритмы, это к начальнику — ругаться! vaa>>можно конечно и на vb хреначить, но это же не наш метод. vaa>>на крайняк может есть коннектор к локальным БД типа sqlite в память грузить и там джоинить. vaa>>или в excel прямо там же тоже что-то имеется для объедиения.
P>в excel можно P>1) функция ВПР() но она еще медленнее P>2) можно через olap -> модель данных -> язык olap запросов MDX -> сводная таблица, но это для меня пока сложновато — это целый отдельный мир непохожий на sql
P>я думал кто-то подскажет как вообще на уровне кода на C# делается аналог лефт джойна на многомерных массивах чисел P>мысль было что как-то через объединение массивов и быструю сортировку по id (на быстрых алгоритмах сортировки)
Можно сделать join с помощью linq. Не знаю как будет по скорости.
Здравствуйте, paradok, Вы писали:
P>Здравствуйте, BlackEric, Вы писали:
BE>>Можно сделать join с помощью linq. Не знаю как будет по скорости. BE>>Join two tables using LINQ Query and order based two parameters
P>попробую!, но скорее всего оно все равно транслируетсz в sql left join и отправляется на сервер.
Это уже зависит от того над чем вы проводите операции.
Вытягивайте данные в DataTable и с ними уже работайте. Или какие-то коллекции подберите.
Здравствуйте, paradok, Вы писали:
P>Из sql studio запрос left join по id выполняется за 3..5 сек, отлично! (с компа разраба, с повыш. правами) P>из хранимой процедуры — 5..10 минут! Кошмар ! (с компов обычных юзеров) P>код строго один и тот же!
Код разный по описанию. Из студии — запрос, из экселя — хранимка, в которую запрос обернут. Это два разных запроса с двумя разными планами выполнения.
Если хранимку из студии запустить — результат какой будет?
P>Кажется не хватает юзерам выполняющему вызов хранимой процедуры каких-о прав и ресурсов (памяти например)...
С точки зрения SQL Server нет разделения производительности по правам и ресурсам.
Немного гадания на кофейной гуще в попытке помочь.
С учётом, что простой вывод содержимого таблиц в Эксель быстрый, другие потенциальные причины типа пропускной способности сети и прочего я бы не рассматривал, пока не рассмотрены более вероятные причины.
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)
Здравствуйте, paradok, Вы писали:
P>нет доступа, это высоко нагруженная система с тысячами юзеров P>- админ жесток, ничего не дает.
Этот админ — DBA или эникейщик? Если второе, то какое он имеет отношение к администрированию СУБД?
А если первое, то почему не помогает с решением проблемы? Это его прямая обязанность.
P>да и какой там план ?!
А вот это и интересно. Actual execution plan тебе даст достаточный объём информации о том, как имеено SQL Server выбирает эти данные, даже в случае простого запроса.
Тем более, что простые запросы хранимки и селекта куда проще сравнить и найти разницу.
P>это полный реальный запрос.
Ну и как выглядит план для запроса и для хранимки?
"Потерял дар речи за зря"(с).
Re: Подскажите алгоритм быстрого left join (ms t-sql)
P>ВОПРОС: P>Подскажите какие алгоритмы применяются для быстрого left join
Вообще-то на уровне СУБД уже реализованиы разные алгоритмы джойна, и планировщик запросов выбирает по его мнению наиболее подходящий. Но иногда может выбрать и неоптимально — поэтому план запроса было бы неплохо посмотреть.
Но зато выбором алгоритма можно управлять вручную с помощью хинтов. Для MSSQL — см., например, здесь. Можешь попробовать сравнить запросы с разными хинтами — будет ли разница в быстродействии
Re[2]: Подскажите алгоритм быстрого left join (ms t-sql)
Здравствуйте, klopodav, Вы писали:
K>Но зато выбором алгоритма можно управлять вручную с помощью хинтов. Для MSSQL — см., например, здесь. Можешь попробовать сравнить запросы с разными хинтами — будет ли разница в быстродействии
Не надо хинты совать бездумно.
Для начала приведи базу в порядок, убедись, что необходимые индексы созданы и поддерживаются в порядке, что статистика своевременно обновляется и репрезентативна, что хранимки написаны грамотно, а уж потом для редких случаев можно хинты указать. И пристально за ними следить, т.к. они станут неэффективны через некоторое время, если база сильно изменится.
"Потерял дар речи за зря"(с).
Re[8]: Подскажите алгоритм быстрого left join (ms t-sql)
_AB>А если первое, то почему не помогает с решением проблемы? Это его прямая обязанность.
к сожалению его прямая обязанность — другая. Сохранность базы, безопасность, безотказность, ровная нагрузка без перегрузов, управление доступом.
1 тыс. юзеров онлайн.
_AB>Тем более, что простые запросы хранимки и селекта куда проще сравнить и найти разницу.
написал заявку в нашу тикет систему тех поддержки, пока доступа к этому нет.
продолжая изучать вижу, что торможение стартует когда из запроса получается более 10 тыс. строк.
думаю все же лимит на память для ограниченных юзеров на хранимые процедуры выставлен в sql сервере.
Re[2]: Подскажите алгоритм быстрого left join (ms t-sql)
план запроса пока нет — доступ у меня закрыт. Придется без него.
_AB>Каждый из них эффективен в разных сценариях. Например, loop join эффективен при малом количестве записей в условной правой таблице. И если хранимка была скомпилирована когда был эффективен loop join, а с тех пор количество записей существенно возросло, время выполнения хранимки вырастет по экспоненте.
да, тестирование в процедуре показало, что кажется есть два порога.
1) до 10 строк на выходе — имхо мелено, 10 сек
2) до 10 тыс. строк на выходе, умеренно — 14 сек
3) более 10 тыс. — замедление, при 100 тыс. уже 5 мин.
Re[3]: Подскажите алгоритм быстрого left join (ms t-sql)
K>>Но зато выбором алгоритма можно управлять вручную с помощью хинтов. Для MSSQL — см., например, здесь. Можешь попробовать сравнить запросы с разными хинтами — будет ли разница в быстродействии _AB>Не надо хинты совать бездумно.
_AB>Для начала приведи базу в порядок, убедись, что необходимые индексы созданы и поддерживаются в порядке, что статистика своевременно обновляется и репрезентативна, что хранимки написаны грамотно, а уж потом для редких случаев можно хинты указать. И пристально за ними следить, т.к. они станут неэффективны через некоторое время, если база сильно изменится.
Как минимум их можно использовать в процессе отладки для проверки гипотезы "тормоза из-за того, что выбран не тот алгоритм джойна". При том, что как ТС указал — получить доступ к плану запроса у него проблематично.
А так — да, для реальной эксплуатации базы они нужны редко, лучше обходиться другими средствами.
Re[3]: Подскажите алгоритм быстрого left join (ms t-sql)
_AB>Для начала приведи базу в порядок, убедись, что необходимые индексы созданы и поддерживаются в порядке, что статистика своевременно обновляется и репрезентативна, что хранимки написаны грамотно, а уж потом для редких случаев можно хинты указать. И пристально за ними следить, т.к. они станут неэффективны через некоторое время, если база сильно изменится.
индексов нет. 2 таблицы по 200..300к, обе обновляются 1 раз в 3 мин.
код в хранимке максимально простой
select * from table1 left join table2 on table1.id = table2.id
Думаете надо пытаться пересоздавать индексы при каждом вызове процедуры?
P>индексов нет. 2 таблицы по 200..300к, обе обновляются 1 раз в 3 мин.
Ну чисто в порядке гадания на кофейной гуще — а что понимается под "обновляется"? Там добавляются-меняются записи в небольшом количестве? Или возможна ситуация, когда таблица была почти пустая, а при очередном обновлении фигак — и добавилось 200к записей?
Если второй вариант — тогда как раз было бы подозрение на то, что старый план запроса может стать неоптимальным.
Re: Подскажите алгоритм быстрого left join (ms t-sql)
Здравствуйте, 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)
Здравствуйте, gandjustas, Вы писали:
G>Проблема гуглится https://www.sommarskog.se/query-plan-mysteries.html
спасибо! плюсанул! — изучаю.
G>Как связаны память и время выполнения?
что будет если вся таблица не поместится в отведенную процессу оперативную память и начнется свопирование на диск в виртуальную память?
G>Объяви процедуру с опцией WITH RECOPILE и будет тебе счастье.
попробовал, ничего не изменилось.
G>PS. При чем тут раздел "алгоритмы" ?
ну типа хотел полностью свой left join имплементировать
подумал возможно дело не в памяти, а в каких-то лимитах на юзера по скорости обмена по сети... или по файловой системе... если такое вообще возможно...
попробовал одну из таблиц копировать в базу к которой у меня почти админские права и которая на другом тестовом сервере — стало быстрее, но время отработки прыгает...нестабильно...
но для других юзеров не прокатывает, медленно, у которых обычные права к этой этой базе. в идеале надо бы процедуру запускать только с моим правами, но пока админ не дал добро.
так что... пока думаю...
Здравствуйте, 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)
Здравствуйте, klopodav, Вы писали:
K>Как минимум их можно использовать в процессе отладки для проверки гипотезы "тормоза из-за того, что выбран не тот алгоритм джойна". При том, что как ТС указал — получить доступ к плану запроса у него проблематично.
Какая проблема нажать Ctrl+M в студии и запустить выполнение хранимки?
"Потерял дар речи за зря"(с).
Re[4]: Подскажите алгоритм быстрого left join (ms t-sql)
Здравствуйте, 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)
проблему на 3+ удалось решить
копированием 2-х таблиц в базу где у меня почти все права и выполнения left join в ней хранимой процедурой в ней же.
Права на выполнение процедуры и чтению данных с этой базы были выданы всем нужным юзерам.
То есть решил чисто огранизационными методами...
но осадочек остался... буду еще копать в направлении планов выполнения
Re: Подскажите алгоритм быстрого left join (ms t-sql)