patternsqlModerate
When should the IGNORE_DUP_KEY option be used on an index?
Viewed 0 times
theusedoptionignore_dup_keyshouldindexwhen
Problem
Someone said it's preferable to craft your queries to avoid duplicate key exceptions, but I'm not convinced that's more performant that just setting
My goal is to ensure a row or set of rows exists for one or more users, before attempting to update those rows. I do this, so that when I attempt to update the row with an update statement like the one below, and no rows are affected, it's because the
I could run
I'm curious whether it's more performant to just turn on
This becomes even more important, when I'm checking for and initializing multiple records at once. For example, if I need to ensure records for thousands of users exist in a single update statement, the logic would be much simpler if I just ran that insert statement up-front, letting it ignore duplicate keys. Avoiding duplicates would be more complex, because I'd have to first query the table for which records don't exist, then attempt to add just those records (again, ignoring duplicate keys). Just inserting may be faster, even if all the records exist.
I could meet it halfway and check whether any of the records are missing, such as with a left join or a
IGNORE_DUP_KEY = ON for the index.My goal is to ensure a row or set of rows exists for one or more users, before attempting to update those rows. I do this, so that when I attempt to update the row with an update statement like the one below, and no rows are affected, it's because the
[Count] portion of predicate wasn't satisfied, as opposed to the row not existing at all (i.e. the [ID] portion of the predicate not being satisfied):UPDATE [Inventory]
SET [Count] = [Count] + 1
WHERE [ID] = 3
AND ([Count] + 1) <= @MaxInventoryI could run
EXISTS(SELECT 1 From [Inventory] WHERE [ID] = 3 to check for that single row, and only insert the row if it does not exist. That simply avoids unnecessary inserts. The insert, if necessary, would still have to contend with concurrent transactions, so duplicate key exceptions can still occur.I'm curious whether it's more performant to just turn on
IGNORE_DUP_KEY in this scenario, rather than allowing the error to be thrown and caught. Specifically, I'm curious if it's as-fast or possibly even faster than running an exists check, to just attempt to insert the record and let it ignore duplicate keys.This becomes even more important, when I'm checking for and initializing multiple records at once. For example, if I need to ensure records for thousands of users exist in a single update statement, the logic would be much simpler if I just ran that insert statement up-front, letting it ignore duplicate keys. Avoiding duplicates would be more complex, because I'd have to first query the table for which records don't exist, then attempt to add just those records (again, ignoring duplicate keys). Just inserting may be faster, even if all the records exist.
I could meet it halfway and check whether any of the records are missing, such as with a left join or a
COUNT coSolution
It's definitely an atypical setting to enable for an index. I don't think you're going to find many people who jump up and talk about using it.
Of course, there are a couple helpful posts on the subject by Paul White:
If your concern is around upsert patterns (or something similar), this article by Michael Swart is really informative:
Of course, there are a couple helpful posts on the subject by Paul White:
- IGNORE_DUP_KEY slower on clustered indexes
- A creative use of IGNORE_DUP_KEY
If your concern is around upsert patterns (or something similar), this article by Michael Swart is really informative:
- SQL Server UPSERT Patterns and Antipatterns
Context
StackExchange Database Administrators Q#247090, answer score: 10
Revisions (0)
No revisions yet.