2008-09-24 3 views
8

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

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

ответ

3

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

2

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

+0

Oracle имеет `v $ session_longops`: http://docs.oracle.com/cd/E11882_01/server.112/e25513/dynviews_3022.htm#i1415618 – 2014-02-05 21:45:32

0

Если вы используете Toad, вы можете сгенерировать набор инструкций INSERT из таблицы и настроить его для фиксации на входной частоте пользователя. Вы можете немного изменить свои сценарии, а затем посмотреть, сколько новых данных было зачислено, когда вы идете.

+0

Нет, не используя Жаба. Если было бы легко разбить инструкции INSERT, я мог бы получить обновление выполнения между ними, но это не работает для операторов INSERT INTO SELECT. – 2008-09-24 20:18:17

2

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

Я хотел бы отметить, что этот подход не будет столь же эффективным, как только делает один большой ВСТАВКУ

+0

так я и делал это раньше. Подтвердите, что это путь медленнее. – 2008-09-24 20:14:37

+0

Я мог бы попробовать в любом случае. добавьте 'where row_id между ...' в основную таблицу в join, а затем цикл для каждого раздела. Я могу справиться с этим немного медленнее, поэтому нам нужно будет увидеть, насколько он медленнее. – 2008-09-24 20:22:57

3

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

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

+0

Хм, это хороший момент, я так и не подумал об этом. – 2008-09-24 20:15:53

5

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

+0

Спасибо за ссылку, ее довольно интересно читать! – 2008-09-24 20:13:54

3

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

0

Вы можете имитировать эффект для своих пользователей, посчитав несколько прогонов, а затем продвигаясь вперед по средней записи/второй скорости.

Единственные другие способы будут

1 - Обратитесь к API вашего двигателя базы данных, чтобы увидеть, если это делает какое-либо положение для этого

или

2 - Перерыв Добавленное в много меньше заявления и сообщать о них по мере поступления. Но это окажет значительное отрицательное влияние на производительность.

0

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

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

1

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

2

Вот что я хотел бы сделать (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' 

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

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' 
0

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

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

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

Смежные вопросы