问题
I'm trying to improve the performance of a multi-row INSERT query, and the biggest factor at the moment according to the query plan is a FK validation against a large parent table.
I know that the INSERT query will not be inserting data that violates the FK, because it is an INSERT INTO ... SELECT ... FROM query where the SELECT involves an INNER JOIN to the parent table on the key columns, so it's not possible that invalid values will be present in the inserted rows.
I do not want to disable the FK globally. I don't want to open a window when other queries could potentially insert bad data, and locking the table and disabling the FK before performing the INSERT doesn't help because re-enabling the FK after the INSERT implies revalidating all the rows (WITH CHECK) before the engine will trust the FK, and both tables are large (potentially tens of millions of rows, and it's a multi-column natural key).
Is there any way in MSSQL to disable the validation of a specific foreign key just during the scope of a single INSERT query? I'm sincerely hoping (without much hope[1]) that I've just missed the documentation where that option is explained.
[1] Why would the engine trust the user to not use that option on a query that might insert bad data? It seems like that would be little more than syntactic sugar for the LOCK TABLE - DISABLE FK - INSERT - ENABLE FK - UNLOCK TABLE approach. But I have to ask just in case...
回答1:
Sometimes it's the best solution. Usually not, though. No way to do it other than to disable before and reenable afterwards, though.
ALTER TABLE foo NOCHECK CONSTRAINT CK_foo_column
Then, afterwards:
ALTER TABLE foo CHECK CONSTRAINT CK_foo_column
回答2:
You can, but it's a terrible, terrible, terrible decision. And there is no free lunch. At some point, you must validate the constraint - pay now or pay later. And pay later will eventually mean that your assumption (all the rows are valid) will be proved false.
https://docs.microsoft.com/en-us/sql/relational-databases/indexes/disable-indexes-and-constraints
As @Randeep mentions, sql server does not automatically create an index to support a FK. And this can't be done for single statement or a single connection - it is global to all users and the particular table.
来源:https://stackoverflow.com/questions/44319157/sql-server-how-to-disable-foreign-key-validation-during-a-single-insert-query