Skew and lock contention are generally two different issues.
About skew
In a nutshell, skew is a matter of probability distribution. A good database index is one that has a uniform-ish distribution. Roughly the same number of records should have "blue" in an index field as they do "red" (and all other colors). If you have index key(s) that show up a lot more than the average, then you have skew.
The reason why skew matters is because Salesforce uses relationship fields (Master-Detail, Lookup, External Ids (a pseudo-relationship in my eyes)) as indices.
Database indices allow fast (back-end) access to a (usually) small subset of the overall data pool. Smaller datasets are easier to process, which is important for multi-tenant services like what Salesforce provides. If your index doesn't eliminate as much of the overall data pool as the average index does, then it's not as effective.
Anything that can be used as an index for a query can experience skew. This includes M-D relationships, lookup relationships, the standard Name field on objects, the standard email field on objects, RecordTypeId, etc...
Skew mostly comes into play with query selectivity. You can have skew with both M-D and lookup relationships
About lock contention
Row locking is used as a way to ensure data integrity.
A record lock prevents any other processes from making changes to the locked record, so if we start with an Opportunity with an Amount
of $10, and two Line Items are added (one $3, one $5), we end up with $18 as the amount on the Opp (instead of potentially $13 or $15).
If a process tries to access a record, and it's locked, Salesforce will wait/retry for up to 10 seconds. If a lock is required and cannot be obtained, you'll get a UNABLE_TO_LOCK_ROW
exception.
When these issues combine
M-D relationships have a few big consequences.
- The Detail record cannot exist without a Master record to be related to
- Record ownership and sharing is determined by the master object
- You can define rollup summary fields on the Master object
- The Parent (and potentially grandparent) record undergoes a save procedure as part of executing a trigger on the Detail object (if there is a rollup summary field or if the child record is part of a cross-object workflow)
Executing a trigger on a record means that that particular record is locked for the duration of that trigger.
The more child records you have related to a parent record, the higher the chance that you'll be trying to simultaneously operate on a locked, parent record.
I'm not sure if we should take the "lookup record is locked unless the lookup field is not configured to clear the field if the lookup record is deleted" literally, but the same principle applies.
Takeaway
The more records you have related (M-D or lookup) to a given record, the more likely you are to run into an issue with lock contention.