2017-10-09 116 views
0

我们的数据库存在严重问题。我们使用SQL Server 2014与2008兼容。数据库锁定问题

每天早上,我们正在获取数据库锁定问题和数据库使用100%cpu。 因此,我们每天早上修复此问题的方法是修改以下存储过程,并在添加和删除语句中的NoLock和再次运行过程之间切换,并且数据库很高兴。所以我们不知道为什么我们有时需要添加NoLock,有时不需要添加。

ALTER Procedure [dbo].[ScanBox] 
(
@KollieID varchar(50) = '', 
@SupplierID int = 0, 
@BuyerID int = 0 
) 
As 
Set NoCount On 

IF @kollieid <> '' AND @supplierid >0 
BEGIN 

    SELECT TRPO_KollieID.ID, OrderID, ISNULL(BoxNo, - 1) AS BoxNo, ISNULL(KollieID, '') AS KollieID, KollieNumber, 
      ISNULL(LastStatus, - 1) AS LastStatus, LastStatusTime, ISNULL(LastStatusPDA, - 1) AS LastStatusPDA, 
      ISNULL(LastStatusTDLogin, '') AS LastStatusTDLogin, ISNULL(OrginalKollieID,'') AS OrginalKollieID, 
      ISNULL(OS.StatusName, '') AS LastStatusText , ISNULL(OrderStatusExternalText,'') AS OrderStatusExternalText , 
      ISNULL(Terminal, '') AS Terminal, ISNULL(TerminalZone,'') AS TerminalZone 
    FROM TRPO_KollieID 
    WITH (NOLOCK) 
      LEFT OUTER JOIN OrderStatus os WITH (NOLOCK) on OS.StatusID = TRPO_KollieID.LastStatus  
    WHERE TRPO_KollieID.KollieID = @KollieID AND (OrderID IN (SELECT TRPO_Header.ID 
         FROM TRPO_Header WITH (NOLOCK) 
          INNER JOIN TRPO_KollieID WITH (NOLOCK) ON TRPO_KollieID.OrderID = TRPO_Header.ID 
         WHERE TRPO_Header.SupplierID = @supplierid AND TRPO_Header.Status <> 'A' AND TRPO_KollieID.KollieID = @kollieid)) 
END 
ELSE IF @kollieid <> '' AND @BuyerID >0 
BEGIN 

    SELECT TRPO_KollieID.ID, OrderID, ISNULL(BoxNo, - 1) AS BoxNo, ISNULL(KollieID, '') AS KollieID, KollieNumber, 
      ISNULL(LastStatus, - 1) AS LastStatus, LastStatusTime, ISNULL(LastStatusPDA, - 1) AS LastStatusPDA, 
      ISNULL(LastStatusTDLogin, '') AS LastStatusTDLogin, ISNULL(OrginalKollieID,'') AS OrginalKollieID, 
      ISNULL(OS.StatusName, '') AS LastStatusText , ISNULL(OrderStatusExternalText,'') AS OrderStatusExternalText , 
      ISNULL(Terminal, '') AS Terminal, ISNULL(TerminalZone,'') AS TerminalZone 
    FROM TRPO_KollieID 
    WITH (NOLOCK) 
      LEFT OUTER JOIN OrderStatus os WITH (NOLOCK) on OS.StatusID = TRPO_KollieID.LastStatus 
    WHERE TRPO_KollieID.KollieID = @KollieID AND OrderID IN (SELECT TRPO_Header.ID 
         FROM TRPO_Header WITH (NOLOCK) 
          INNER JOIN TRPO_KollieID WITH (NOLOCK) ON TRPO_KollieID.OrderID = TRPO_Header.ID 
         WHERE TRPO_Header.BuyerID = @BuyerID AND TRPO_Header.Status <> 'A' AND TRPO_KollieID.KollieID = @kollieid)  



END 

我们已经尝试是

  1. 我们试图索引数据库。
  2. 试图设置的IsolationLevel读提交快照

没有帮助我们。有没有人有解决这个问题的好主意?

+0

给我们这个查询的执行计划。也许你没有以正确的方式编制数据库索引。另外 - 不要使用NOLOCK提示。 –

回答

1

重新编译可以帮助你,而不是nolock。尝试添加OPTION(RECOMPILE)或OPTION(OPTIMIZE)...或者获得查询paln

+0

非常感谢。看起来很有趣。我明天会就此回复你。正如你在我们的查询中看到的那样,我们有If else语句。你认为我们应该有不同的存储过程吗? – DevelopmentIsMyPassion

+0

看起来像OPTION(OPTIMIZE)已经工作。再等两天再检查一下 – DevelopmentIsMyPassion

0

如果您使用的是Read Committed Snapshot Isolation Level,这意味着读者不会阻止编写者,编写者也不会阻止读者。所以在这种情况下nolock提示是无用的,我会建议你删除它们。

我认为基本问题是在另一件事情,但锁定,也许这存储过程执行缓慢,并使用许多服务器资源。