我可以在多个CPU上展开长时间运行的存储过程吗?

时间:2010-03-05 17:05:53

标签: sql-server multithreading sql-server-2008 stored-procedures performance

[也在SuperUser上 - https://superuser.com/questions/116600/can-i-spead-out-a-long-running-stored-proc-accross-multiple-cpus]

我在SQL Server中有一个存储过程获取,并解密一个数据块。 (在这种情况下是信用卡。)

大多数情况下,性能是可以忍受的,但有几个客户的过程非常缓慢,需要花费1分钟才能完成。 (确切地说,从SQL Server返回59377ms,但根据负载可能会有几百毫秒的变化)

当我观察这个过程时,我发现SQL只使用一个proc来执行整个过程,通常只有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

3 个答案:

答案 0 :(得分:0)

对于超级用户组(DBA)来说,这可能是一个更好的问题

答案 1 :(得分:0)

考虑信用卡号码非常好 - Visa / MasterCard 16位CC的最后一位是校验和值。您是否考虑过自己的并行性,例如,通过让每个线程获取模数(4)= thread_id的CC数字?假设n个CPU /核心/今天它们正在调用它们,你不需要超过4个(2 *核心)并行处理线程。

答案 2 :(得分:0)

是 - 将游标重写为基于集合的查询,SQL Server优化程序应根据基础数据的大小自动并行化(或不同步)。除了一些基本的最佳实践(如避免游标)之外,不需要“特殊”开发工作来使SQL Server使用并行性。它会自动决定是否可以在多个proc上使用并行线程,如果这样做很有用,那么它可以在运行时为你分割工作。