[Также в SuperUser - https://superuser.com/questions/116600/can-i-spead-out-a-long-running-stored-proc-accross-multiple-cpus]
У меня есть хранимая процедура в SQL-сервере, которая получает и расшифровывает блок данных.(Кредитные карты в данном случае.)
В большинстве случаев производительность терпима, но есть пара клиентов, у которых процесс мучительно медленный и занимает буквально 1 минуту.(Ну, если быть точным, 59377 мс для возврата из SQL Server, но он может варьироваться на несколько сотен мс в зависимости от нагрузки)
Когда я наблюдаю за процессом, я вижу, что для выполнения SQL используется только один процессвесь процесс, и, как правило, только proc 0.
Есть ли способ, которым я могу изменить свой хранимый процесс, чтобы SQL мог многопоточность процесса?Возможно ли даже обмануть и разбить вызовы пополам (верхние 50%, нижние 50%) и распределить нагрузку, как грубый взлом?(просто плевок здесь)
Мой сохраненный процесс:
USE [Commerce]
GO
/****** Object: StoredProcedure [dbo].[GetAllCreditCardsByCustomerId] Script Date: 03/05/2010 11:50:14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[GetAllCreditCardsByCustomerId]
@companyId UNIQUEIDENTIFIER, @DecryptionKey NVARCHAR (MAX)
AS
SET NoCount ON
DECLARE @cardId uniqueidentifier
DECLARE @tmpdecryptedCardData VarChar(MAX);
DECLARE @decryptedCardData VarChar(MAX);
DECLARE @tmpTable as Table
(
CardId uniqueidentifier,
DecryptedCard NVarChar(Max)
)
DECLARE creditCards CURSOR FAST_FORWARD READ_ONLY
FOR Select cardId from CreditCards where companyId = @companyId and Active=1 order by addedBy desc
--2
OPEN creditCards
--3
FETCH creditCards INTO @cardId -- prime the cursor
WHILE @@Fetch_Status = 0
BEGIN
--OPEN creditCards
DECLARE creditCardData CURSOR FAST_FORWARD READ_ONLY
FOR select convert(nvarchar(max), DecryptByCert(Cert_Id('Oh-Nay-Nay'), EncryptedCard, @DecryptionKey)) FROM CreditCardData where cardid = @cardId order by valueOrder
OPEN creditCardData
FETCH creditCardData INTO @tmpdecryptedCardData -- prime the cursor
WHILE @@Fetch_Status = 0
BEGIN
print 'CreditCardData'
print @tmpdecryptedCardData
set @decryptedCardData = ISNULL(@decryptedCardData, '') + @tmpdecryptedCardData
print '@decryptedCardData'
print @decryptedCardData;
FETCH NEXT FROM creditCardData INTO @tmpdecryptedCardData -- fetch next
END
CLOSE creditCardData
DEALLOCATE creditCardData
insert into @tmpTable (CardId, DecryptedCard) values ( @cardId, @decryptedCardData )
set @decryptedCardData = ''
FETCH NEXT FROM creditCards INTO @cardId -- fetch next
END
select CardId, DecryptedCard FROM @tmpTable
CLOSE creditCards
DEALLOCATE creditCards