0

如何在 sql server 2008 中优化以下查询。特别是我需要优化的选择查询。(例如,DB = 10000 中的总记录,如果在 9999 行中消耗了_flag ='flase',则需要花费很多时间来检索单个记录)

DECLARE @proxyAcctToken nvarchar(50) 
DECLARE @pmtAcctToken varchar(50)
 DECLARE @ErrorCode varchar(50)
DECLARE @returnMessage varchar(1000)
DECLARE @ErrorStep varchar(100)
DECLARE @tokenSeqNo int
DECLARE @count int
SELECT @count=100000

WHILE(@count>0)
   BEGIN
          SELECT @ErrorCode = @@ERROR
          BEGIN TRY
                 SELECT top 1 @tokenSeqNo=S_NO,@pmtAcctToken = PMT_ACCT_TOKEN, @proxyAcctToken=PROXY_PMT_TOKEN
                 FROM PCTransDB.dbo.MIG_TOKEN_DUMP WHERE CONSUMED_FLAG = 'false'

                 UPDATE PCTransDB.dbo.MIG_TOKEN_DUMP SET CONSUMED_FLAG = 'TRUE', CONSUMED_BY = 'MIGBATCH' WHERE S_NO = @tokenSeqNo
                 PRINT @count


          SELECT  @ErrorCode  = 0

          /*************************************
          *  Return from the Stored Procedure
          *************************************/
   END TRY

   BEGIN CATCH   
   PRINT 'IN CATCH BLOCK'
   END CATCH
   SELECT @count = @count-1
   SELECT @proxyAcctToken = null
   SELECT @pmtAcctToken =null
 END

注意:表格详细信息

  Column Nmae         DataType  IsNullable
  S_NO                  int      NO
  PROXY_PMT_TOKEN   nvarchar     NO
  PMT_ACCT_TOKEN    nvarchar     NO
  CONSUMED_FLAG        bit       NO
  CONSUMED_BY       nvarchar    YES
4

1 回答 1

0

如果我正确理解您的代码,您基本上是TOP 1从表中选择行 where CONSUMED_FLAG = 'false',然后您将这一行更新为拥有-CONSUMED_FLAG = 'true'并且CONSUMED_BY = 'MIGBATCH'您这样做了 10'000 次 - 对吗?

顺便说一句:在TOP 1没有 an的情况下做 aORDER BY是毫无意义的——TOP 1你得到了什么?你没有定义一个顺序——那么你期望什么顺序TOP 1给你“最上面”的行??

那么你为什么不这样做:

-- use a CTE (Common Table Expression) to select the TOP 10000 rows
-- you need to SPECIFY AN ORDER BY for this to make sense!
;WITH CTE AS
(
    SELECT TOP 10000 
        S_NO
    FROM    
        PCTransDB.dbo.MIG_TOKEN_DUMP 
    WHERE
        CONSUMED_FLAG = 'false' 
    ORDER BY 
         ??????
)
UPDATE 
    PCTransDB.dbo.MIG_TOKEN_DUMP 
SET 
    CONSUMED_FLAG = 'TRUE', CONSUMED_BY = 'MIGBATCH' 
FROM 
    CTE 
WHERE 
    CTE.S_NO = PCTransDB.dbo.MIG_TOKEN_DUMP.S_NO

基本上,只需通过在 CTE 中选择它们来定义要更新的内容(哪些行),然后运行一个UPDATE语句来更新所有选定的行。完毕。没有凌乱的循环,什么都没有——就像一个魅力!

于 2013-03-01T08:14:35.490 回答