Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > Индикатор выполнения SQL запроса


Автор: falcon39 26.3.2006, 12:59
Возможно ли сделать так чтоб был виден процесс выполнения запроса.

Автор: Bose 27.3.2006, 14:18
нет. потому что запрос выполняется на сервере. хотя... если удасться каким-то образом получить эту информацию от сервера... что маловероятно smile

Автор: Vit 27.3.2006, 16:10
Нет, невозможно

Автор: AKN 29.3.2006, 15:20
В принципе, если время формирования запроса не критично, можешь разбить большой запрос на 10 маленьких и в progreebar`е добавлять по 10 %..., но опять таки - время выполнения возрастет...

Автор: Tror 29.3.2006, 15:30
smile

Цитата(AKN @ 29.3.2006, 15:20 Найти цитируемый пост)
если время формирования запроса не критично
smile smile

тогда можно использовать текстовый файл smile smile

Автор: Vit 29.3.2006, 16:01
Цитата(Tror @ 29.3.2006, 06:30 Найти цитируемый пост)
тогда можно использовать текстовый файл 


Ничего смешного нет, на самом деле разбиение одного запроса на несколько мелких достаточно частый приём, причём со многими целями:

1. Для прогресбара - если запрос выполняется например 6 часов, то желательно уже через час знать прошло 30%, 10% или 1% времени...

2. Для устранения длительных блокировок. Например если мне надо сделать Update 10 миллионов записей в табице размером в 100 миллионов, то ожибаемое время выполнения составит как минимум от 20 минут, а по хорошему может и несколько часов, в это время если эта таблица сильно загружена запросами вся корпорация не сможет работать... поэтому логично например делать этот Update кусками по 1000 записей за раз с промежутками в секунду между запросами чтобы дать возможность "пройти" другим запросам. Да, конечно, мой Update будет идти в 3-5 раз дольше, но за то база данных на это время будет оставаться работоспособной.

Кстати не факт что разбитый запрос будет выполняться медленнее - большие запросы могут потребовать гораздо большего свопинга памяти и гораздо большей нагрузки на дисковую систему по размещению временных данных. Поэтому на не очень продвинутом железе, небольшом объёме памяти и медленной дисковой системе вполне вероятен вариант когда по кускам выполняться запрос будет быстрее.

Автор: AKN 30.3.2006, 11:33
Цитата

Например если мне надо сделать Update 10 миллионов записей в табице размером в 100 миллионов, то ожибаемое время выполнения составит как минимум от 20 минут, а по хорошему может и несколько часов, в это время если эта таблица сильно загружена запросами вся корпорация не сможет работать...

а стоит ли использовать такие гиганты? 100 млн записей, это же самый простой селект будет выполнятся минутами ( в зависимости от таблицы и условий конечно). Не логичнее ли в данном случае составить несколько таблиц, разделенных, например, по дате (каждые пол года создается новая таблица, а перед выполнением запроса условие запроса анализируются, и на основании анализа программно выбираются таблицы, из которых будет состоять выборка). Я работаю системным администратором в корпоративной сети супермаркетов, и когда каждый день в таблицу инсертится около 120000 записей, это похоже, единственный выход....

Автор: Vit 30.3.2006, 16:30
Цитата(AKN @ 30.3.2006, 02:33 Найти цитируемый пост)
а стоит ли использовать такие гиганты? 100 млн записей, это же самый простой селект будет выполнятся минутами ( в зависимости от таблицы и условий конечно).


Не знаю что вы делаете, скорее всего вам нужен хороший DBA. Таблицы в 100 млн. записей я не могу назвать даже очень большими, скорее средними, обычными. При правильных индексах, хинтах и блокировках обычный селект выполняется на 100000000 записей практически мгновенно, если он конечно не должен возращать миллионы записей. Я работаю на MS SQL Server, корпоративная база данных, селект "через (inner join)" 3 таблицы размером по 20 миллионов записей каждая с возвращением 500000 записей выполняется 8-10 секунд, при том что к базе одновременно подкючено более 200 клиентов и выполняется до 10 запросов в секунду...
По моим представлениям большая таблица - это от 100 миллионов записей и больше, и то при правильной архитектуре ни один запрос на таких таблицах кроме массовых Update/Delete/Insert не должен идти более 5 минут. 5 минут - это мой личный лимит, если мой запрос выполняется дольше, я считаю что я что-то делаю неправильно - неправильная структура базы данных, кривой запрос, неправильные хинты, неправильная логика, неправильный дизайн системы и т.п. Лично для себя решил что ни один мой запрос не должен выполнятся более 5 минут. Иногда это чертовски сложно достич, иногда над запросом приходится работать несколько дней, использовать временные таблицы, табличные переменные, даже переиндексацию таблиц на время запроса и т.п но уже 7 лет удаётся эту цифру удерживать, хотя работаю с корпоративными системами где размер базы данных приближается к терабайту, количество одновременных подключений колеблется от нескольких сотен до нескольких тысяч, а количество запросов как правило превышает 10-20 в секунду.

99% медленных запросов - это результат либо незнания, либо отсутствия опыта, либо ленности. Только вчера коллега мне жаловался что его запрос выполняется более 5 минут и часто вылетает или по "dead lock" или по "time out" - результат 4 часов детального изучения планов выполнения запроса и попыток оптимизации привёл к тому что его запрос теперь выполняется менее 10 секунд и ничего не блокирует.

Цитата(AKN @ 30.3.2006, 02:33 Найти цитируемый пост)
Я работаю системным администратором в корпоративной сети супермаркетов, и когда каждый день в таблицу инсертится около 120000 записей, это похоже, единственный выход....


Это не очень много, такие объёмы можно считать незначительными, за год не наберётся и 50 миллионов, разве что записи содержат большие blob и memo поля, но тогда нагрузка скорее не на базу а на сетку

Автор: brabus 31.3.2006, 16:18
если под запросом понимается sql код, возвращающий набор данных, то , например в delphi , в используемом компоненте доступа ловиться что то наподобие OnFetchRecord, и рисуется кол-во выбранных строк. общее кол-во неизвестно. поэтому прогрессбар наверное не катит.

Автор: Vit 1.4.2006, 07:21
Цитата(brabus @ 31.3.2006, 07:18 Найти цитируемый пост)
если под запросом понимается sql код, возвращающий набор данных, то , например в delphi , в используемом компоненте доступа ловиться что то наподобие OnFetchRecord, и рисуется кол-во выбранных строк. общее кол-во неизвестно. поэтому прогрессбар наверное не катит.



Угу только это отображает процесс перекачки данных с сервера на клиент а не реальное выполнение запроса на сервере... Запусти что-нибудь типа

Код

Select ..., Count(*) From...
Left outer join ... on ...
Group By ...
Having...
Order by ..


и получишь, что на больших таблицах запрос выполняется в течение 3 минут, а результатом является 2 строчки которые передаются на клиент мгновенно... И OnFetchRecord срабатывает за мгновение до конца выполнения, а в течение 3х минут абсолютный "глухарь" - запрос варится сам в себе на сервере и о его прогрессе можно только догадываться...

Автор: brabus 11.4.2006, 10:45
Цитата(Vit @ 1.4.2006, 07:21)
[QUOTE
Угу только это отображает процесс перекачки данных с сервера на клиент а не реальное выполнение запроса на сервере... Запусти что-нибудь типа

Код

Select ..., Count(*) From...
Left outer join ... on ...
Group By ...
Having...
Order by ..


и получишь, что на больших таблицах запрос выполняется в течение 3 минут, а результатом является 2 строчки которые передаются на клиент мгновенно... И OnFetchRecord срабатывает за мгновение до конца выполнения, а в течение 3х минут абсолютный "глухарь" - запрос варится сам в себе на сервере и о его прогрессе можно только догадываться...

согласен. с серверной стороны ответа не будет на этот вопрос.
поэтому если отвечать прямо на заданный вопрос - нельзя

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)