2009-11-06 10 views
0

Это скрипт, который принимает очень долгое времяSQL скрипт принимает много времени для извлечения данных

USE [r_prod] 
GO 
SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
-- ============================================= 
-- Author:  Drew Borden 
-- Create date: 4/16/2009 
-- Description: Procedure to populated subdivision extract table 
-- ============================================= 
IF EXISTS(SELECT * FROM sys.procedures WHERE name='sp_extract_subdivision') 
BEGIN 
    DROP PROCEDURE sp_extract_subdivision 
END 
GO 

CREATE PROCEDURE sp_extract_subdivision 
    @subdivsion_cd char(2) 
AS 
BEGIN 
    -- SET NOCOUNT ON added to prevent extra result sets from 
    -- interfering with SELECT statements. 
    SET NOCOUNT ON; 

declare @strap varchar(25) 

-- Clear existing record 
delete from dbo.subdivision_extract 

-- Select list of straps to loop through 
declare strapList cursor for 
select strap from dbo.parcel where county_cd = @subdivsion_cd 

--Loop through straps and populate extract table values 
BEGIN TRY 
    OPEN strapList 
    FETCH NEXT FROM strapList INTO @strap 
    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     IF @strap IS NOT NULL 
     BEGIN 
      insert into dbo.subdivision_extract (acct_num) values (RTRIM(@strap)) 
      exec sp_extract_parcel @strap 
      exec sp_extract_detail @strap 
      exec sp_extract_lnd_c @strap 
      exec sp_extract_parcel_flg @strap 
      exec sp_extract_owner @strap 
      exec sp_extract_mail @strap 
      exec sp_extract_legal_ln @strap 
      exec sp_extract_site @strap 
      exec sp_extract_condo_unit @strap 
      exec sp_extract_personal_x @strap 
      exec sp_extract_personal_x_dist @strap 
      exec sp_extract_phase_in @strap 
      exec sp_extract_p_tax_dist @strap 
      exec sp_extract_parcel_rel @strap 
      exec sp_extract_entzone @strap 
      exec sp_extract_dates @strap 
      exec sp_extract_sales @strap 
      exec sp_extract_sale_dtl @strap 
      exec sp_extract_pchar @strap 
      exec sp_extract_protest @strap 

     END 
     FETCH NEXT FROM strapList INTO @strap 
    END 
    CLOSE strapList 
    DEALLOCATE strapList 
END TRY 

BEGIN CATCH 
    SELECT ERROR_NUMBER() as ErrorNumber, 
      ERROR_MESSAGE() as ErrorMessage, 
      ERROR_PROCEDURE() as ExecutingProcedure, 
      ERROR_LINE() as LineNumber 
    CLOSE strapList 
    DEALLOCATE strapList   
END CATCH 
END 
GO 

Любой способ ускорить это?

+0

Это похоже на SQL Server ... это 2005, 2008 или что-то, что не является SQL Server, но выглядит замечательно? –

+0

@John: ваш вопрос может получить больше просмотров, если вы пометите его с помощью СУБД, которую вы используете. –

+0

Это SQL-сервер 2005 –

ответ

0

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

1

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

1

Настоящая проблема заключается в том, что вы вызываете 20 хранимых процедур последовательно с помощью курсора.

Я ненавижу курсоры для начала, и придумал решение для этого в предыдущих проектах.

Вместо того, чтобы получать переменную из курсора, можете ли вы последовательно выполнить 20 хранимых процедур для всех данных?

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

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

Сколько времени занимает delete from dbo.subdivision_extract? Если это занимает некоторое время, и журнал не требуется (и у вас нет триггеров на столе), попробуйте изменить его на TRUNCATE TABLE dbo.subdivision_extract

TLDR: обновите сохраненные процессы для обработки всех данных, тогда вам понадобится только для вызова 20 хранимых процедур каждый раз.

0

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

0

Да, актуально легко исправить: измерить медленное, а затем оптимизировать медленную часть.

Все, что вы опубликовали, - это сценарий T-SQL, который так же непрозрачен, как и в отношении производительности. DELETE, SELECT, итерация курсора с INSERT и связкой EXEC. Проблема может быть в любом месте, поэтому лучшее решение - измерить и посмотреть, где может быть проблема.

Возьмите сценарий и добавьте PRINT GETDATE(); в начале после DELETE после первого FETCH, затем после каждого EXEC и выполните одну итерацию (удалите FETCH внутри цикла). Посмотрите на вывод PRINT, вы можете вывести время, необходимое для выполнения каждого шага. Кто-нибудь из них выделяется?

Прикрепить Профилировщик и монитор событий SP:StmtCompleted с фильтром на Продолжительность. Повторите одну итерацию цикла извлечения. Какие из выступлений отличаются наибольшей продолжительностью?

Запустите сценарий для отдельной итерации в SSMS, но установите флажок Включить фактический план выполнения на панели инструментов. В приведенном показе исполнения, какие заявления выделяются как высокая стоимость относительно партии?

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

Хотя теоретически обработка с ориентированным набором может иметь лучшую производительность, чем курсор, на практике было бы, вероятно, невозможно написать один оператор, который извлекает ту же информацию, что и 20 вызовов выполнения хранимой процедуры, если только эти процедуры не являются экстремально тривиальными ВЫБИРАЕТ.

+0

Спасибо за все входные данные. Это скрипт поставщика, и мне нужно некоторое время, чтобы посмотреть на различные варианты - спасибо снова –

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

  • Нет связанных вопросов^_^