选择屏蔽问题

sha*_*son 4 sql-server-2005 sql-server

数据库没有响应简单的选择语句,如

select * from table
Run Code Online (Sandbox Code Playgroud)

我注意到sys.dm_os_waiting_tasks一个会话被阻塞,阻塞会话指向一个使用 lock & Tran 的存储过程,如下所示

    BEGIN TRAN

declare @min numeric ,@com numeric

select top 1  @com=companyid from tblcompanies
order by newid()



select @min=min(productid) from tblproducts(UPDLOCK)
where companyid=@com and (lockstatus<>1 or lockstatus is null )


update tblproducts
set lockStatus='1'
where productid>=@min and productid<@min+4

select distinct top 4 s.productname,s.productid,s.companyid,r.Type,r.requestType,r.UserID
from tblcompanydetail rd inner join tblproducts s
on rd.productid=s.productid
inner join tblcompanies r
on r.companyid=s.companyid
where s.productid>=@min and s.productid<@min+4


if @@error >0 rollback tran

commit tran
Run Code Online (Sandbox Code Playgroud)

如果我写错了,请告诉我。

Aar*_*and 7

这是我将如何重写这个。内嵌各种评论。这些更改可能有助于减少阻塞,但除非这些都是堆和/或每个表访问都会产生扫描,否则很难看出即使原始文件也会阻塞很长时间......

DECLARE @min INT, @com INT; -- these are INTs, right?

SELECT TOP 1 @com = companyid 
  FROM dbo.tblcompanies -- always use schema prefix
  ORDER BY NEWID(); -- random company? really?

-- Minimize transaction duration. Any real need to select the 
-- random company & perform final select inside the transaction?

BEGIN TRANSACTION;
  BEGIN TRY    

    SELECT @min = MIN(productid) 
      FROM dbo.tblproducts WITH (UPDLOCK)
      WHERE companyid = @com 
      AND (lockstatus <> 1 OR lockstatus IS NULL);

    UPDATE dbo.tblproducts
      SET lockStatus = '1' -- is this column numeric or string?
      WHERE productid >= @min AND productid < @min + 4; -- values guaranteed contiguous?

    COMMIT TRANSACTION;

    SELECT -- don't believe DISTINCT or TOP are required here
      s.productname, s.productid,   s.companyid,
      r.Type,        r.requestType, r.UserID  
    FROM dbo.tblproducts AS s
    INNER JOIN dbo.tblcompanies AS r
      ON r.companyid = s.companyid
    WHERE s.productid >= @min AND s.productid < @min + 4
    AND EXISTS -- since no columns from rd are needed
    ( 
      SELECT 1 FROM dbo.tblcompanydetail
      WHERE productid = s.productid
    );

  END TRY
  BEGIN CATCH
    ROLLBACK TRANSACTION;
  END CATCH
Run Code Online (Sandbox Code Playgroud)

  • @shawnswanson:调优是一步一步的操作。按照 Aaron 的建议做,更改代码,测试,再次测试(不在生产​​中),然后,如果没有任何变化,请返回详细信息。 (2认同)