Как вывести сообщения о ходе выполнения из оператора SELECT? - PullRequest
8 голосов
/ 24 сентября 2008

У меня есть сценарий SQL, который я хочу выводить сообщения о ходе выполнения во время его работы. Выводить сообщения между операторами SQL легко, однако у меня есть очень долго работающий INSERT INTO SELECT. Есть ли способ, чтобы оператор SELECT выводил сообщения по мере их поступления, например, после каждых 1000 строк или каждые 5 секунд?

Примечание: это для SQL Anywhere, но ответы на любом диалекте SQL будут хорошими.

Ответы [ 12 ]

5 голосов
/ 24 сентября 2008

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

3 голосов
/ 25 сентября 2008

Я работаю в команде разработчиков движка SQL Anywhere, и в настоящее время нет способа сделать это. Я ничего не могу обещать, но мы рассматриваем возможность добавления этого типа функций в будущий выпуск.

3 голосов
/ 24 сентября 2008

Действительно, идея прогресса с операциями на основе множеств (что и используется реляционной базой данных) была бы не слишком полезной, по крайней мере, не так, как отображается с помощью индикатора выполнения (процент выполненных операций против общего числа). К тому времени, когда оптимизатор выяснил, что ему нужно сделать, и действительно понял полную стоимость операции, вы уже выполнили значительную часть операции. Отображение прогресса на самом деле предназначено для итеративных операций, а не операций множества.

Это говорит о вашем общем выполнении инструкции SELECT. Для вставок, которые являются отдельными выписками, существуют разные способы сделать это от отправителя, отслеживая уровень потребления выписок. Если это массовые вставки (выберите, вставьте из и т. Д.), То у вас действительно та же проблема, что я описал выше. Операции над множествами сгруппированы таким образом, что делает отображение типа индикатора выполнения несколько бессмысленным.

3 голосов
/ 24 сентября 2008

Сам по себе SQL не предусматривает такого рода вещи. Любой способ сделать это будет включать в себя общение непосредственно с ядром базы данных и не будет стандартным для всех баз данных.

2 голосов
/ 02 октября 2008

Вот что я бы сделал (синтаксис Sybase / SQL Server):

DECLARE @total_rows int

SELECT  @total_rows = count(*) 
FROM    Source_Table

WHILE   @total_rows > (SELECT count(*) FROM Target_Table) 
BEGIN
    SET rowcount 1000 

    print 'inserting 1000 rows' 

    INSERT  Target_Table         
    SELECT  * 
    FROM    Source_Table s
    WHERE   NOT EXISTS( SELECT 1 
                        FROM   Target_Table t
                        WHERE  t.id = s.id )
END

set rowcount 0
print 'done'

Или вы можете сделать это на основе идентификаторов (предполагается, что идентификатор - это число):

DECLARE @min_id   int, 
        @max_id   int, 
        @start_id int, 
        @end_id   int

SELECT  @min_id = min(id) , 
        @max_id = max(id) 
FROM    Source_Table

SELECT  @start_id = @min_id , 
        @end_id   = @min_id + 1000 

WHILE   @end_id <= @max_id 
BEGIN

    print 'inserting id range: ' + convert(varchar,@start_id) + ' to ' + convert(varchar,@end_id) 

    INSERT  Target_Table         
    SELECT  * 
    FROM    Source_Table s
    WHERE   id           BETWEEN @start_id AND @end_id

    SELECT  @start_id = @end_id + 1, 
            @end_id   = @end_id + 1000 
END

set rowcount 0
print 'done'
2 голосов
/ 24 сентября 2008

Я согласен, что у SQL нет способа сделать это напрямую. Один из способов - вставить ТОП-1000 за раз, а затем распечатать сообщение о состоянии. Затем продолжайте повторять это по мере необходимости (в каком-то цикле). Недостатком является то, что вам потребуется способ отслеживать, где вы находитесь.

Я должен отметить, что этот подход не будет столь же эффективным, как просто сделать одну большую вставку

2 голосов
/ 24 сентября 2008

Конечно, нет стандартного решения SQL для этого. Извините, что я обречен, но я не видел ничего такого, что могло бы сделать это в Oracle, SQL Server, Sybase или MySQL, поэтому я бы не стал слишком надеяться на SQLAnywhere.

1 голос
/ 02 октября 2008

Одна мысль может иметь другой отдельный процесс для подсчета количества строк в таблице, где выполняется вставка, чтобы определить, какой процент из них уже существует. Это, конечно, потребует, чтобы вы знали общее количество в конце. Это, вероятно, будет хорошо, если вы не слишком беспокоитесь о загрузке сервера.

0 голосов
/ 06 февраля 2014

Наткнулся на эту старую ветку в поисках чего-то другого. Я не согласен с идеей, что нам не нужна информация о прогрессе только потому, что это заданная операция. Пользователи часто будут терпеть даже долгое ожидание, если они знают, как долго это будет.

Вот что я предлагаю:

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

0 голосов
/ 02 октября 2008

Если вам нужно это или вы умрете, для вставки, обновления, удаления вы можете использовать некоторую логику триггера с переменными db, и время от времени вы выполняете sql для получения переменных данных и отображения некоторого прогресса для пользователя.

Если вы не хотите его использовать, я могу написать пример и отправить его.

...