Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using foreign key in SQL server and DB locks

I have been working with SQL Server for a long time I always use FKs and indexes when a logic connection between tables exist

Example:

MyTable1
{
    ID      BIGINT IDENTITY (1, 1)  NOT NULL,
    SomeData    NVARCHAR(255)       NOT NULL,
    MyFK        BIGINT          NULL -- this is a FK to MyTable2.ID
}

MyTable2
{
    ID      BIGINT IDENTITY (1, 1)  NOT NULL,
    SomeData    NVARCHAR(255)       NOT NULL
}

Now to the problem, When I execute some bulk update operations on MyTable1 that update MyFK, and in the same time execute an insert statements to MyTable2, we hang till a timeout occur or the update is done and the locks are released.

As far as I know when inserting to a table that has FKs, the DB engine needs to get a lock on the relevant table to validate the FK, and that is the source for the problem.

Things I tries to resolve the problem:

  • removed the lock escalation option on the table http://msdn.microsoft.com/en-us/library/ms184286%28v=sql.105%29.aspx

  • Changing the locks on the index to be row based and not page based http://msdn.microsoft.com/en-us/library/ms189076%28v=sql.105%29.aspx

Both solutions lead me to deadlocks and bad performance.

When I removed the FK, it all worked well, but there is the risk of data corruption.

Questions:

  1. Is there any recommended set of rules on where to use a FK and where not to?
  2. Can you offer me any other solution but removing the FK to overcome my problem?
like image 245
asafrob Avatar asked Nov 03 '22 19:11

asafrob


1 Answers

Just in case the page asasfrob found goes down, the answer it gave was:

Define the primary key on the parent table (TableA) as a non-clustered index. Once you do that, the issue won’t occur since the look-up will occur against the non-clustered index and that won’t be in a locked state since the PK column is not being modified.

like image 51
Fidel Avatar answered Nov 11 '22 11:11

Fidel