Core component of SQL Server for storing, processing, and securing data
Cap MAXDOP at the measured break-even point for SQLCLR-heavy statements and use bounded string parameters when the data is genuinely bounded; no published SQL Server 2025 setting or trace flag is documented as disabling the reported DIAG_OBJECT acquisition.
Recommended mitigation
- Apply
MAXDOP 4to the affected statements based on the supplied measurements. Use the lowest DOP that gives the best elapsed time under representative concurrency:
A query-levelSELECT COUNT_BIG(*) FROM dbo.Repro AS r WHERE dbo.ClrPlusOne(r.Value) = 0 OPTION (MAXDOP 4);MAXDOPhint overrides the server setting, subject to a lower Resource Governor limit, so it isolates the workaround to affected statements rather than reducing parallelism instance-wide.^1^ Do not retainENABLE_PARALLEL_PLAN_PREFERENCEin production unless it is required for a separate, validated reason. Your DOP 1 result indicates that forcing a parallel alternative is counterproductive for this particular per-row SQLCLR workload. - Declare bounded strings as
nvarchar(n), notnvarchar(max), whenever the business maximum is known. SQLCLR scalar invocation occurs once per row and includes generated marshaling code based on the exact parameter types; managed/native transitions also carry execution-environment and security overhead.^2^ - If a parameter must support true LOB values, keep
nvarchar(max)but expose it to the CLR routine asSqlCharsrather thanSqlString.SqlCharsstreams the LOB instead of copying the complete value into managed memory.^3^
These are workload mitigations, not confirmation that either contention path is expected behavior.
What DIAG_OBJECT is protecting
Microsoft’s public documentation does not define the internal structure protected by DIAG_OBJECT, nor establish which SQLCLR call-path component acquires it in SQL Server 2025. The spinlock name and DMV deltas alone cannot identify the owner. Spinlocks serialize access to internal structures, and disproportionate growth in spins and CPU relative to throughput is the documented pattern that warrants call-stack investigation.^4^
There is also no documented SQL Server 2025 trace flag that removes or partitions DIAG_OBJECT. In particular:
- Trace flag 8134 only exposes spinlock activity through the
SPINLOCK_EXTwait type on SQL Server 2025; it is diagnostic, not a fix.^5^ - Trace flags 8099 and 8101 apply specifically to SQL Server 2019 builds and are not documented for SQL Server 2025.^5^
Since disabling lightweight profiling and Query Store made no difference, there is no basis for changing those settings further.
Why KB2887899 does not apply directly
KB2887899 fixed contention on SOS_CACHESTORE and SOS_SELIST_SIZED_SLOCK while building spatial indexes in SQL Server 2012 and 2014. It explains that these locks protected CLR procedure-cache entries and could become a bottleneck when parallel spatial plans invoked a spatial function per row.^6^
That mechanism is relevant circumstantial evidence, but the fix’s published applicability is limited to spatial-index builds on those versions. It does not document a fix for user-written SQLCLR functions or SQL Server 2025.
Also, KB2887899 is not the spatial fix requiring a trace flag. The related KB2896720 introduced trace flag 6530 for many parallel spatial operations on SQL Server 2012/2014.^7^ That flag should not be extrapolated to SQL Server 2025 SQLCLR workloads.
Escalation evidence
This needs a Microsoft Support investigation to map the internal call path and determine whether it is a SQL Server 2025 defect. Add these artifacts to the existing report:
- Before/after deltas from
sys.dm_os_spinlock_statsfor each tested DOP. -
SPINLOCK_EXTwait deltas collected with trace flag 8134 during a short controlled reproduction. - Extended Events
spinlock_backoffandspinlock_backoff_warningcall stacks forDIAG_OBJECT,SOS_CACHESTORE, andSOS_SELIST_SIZED_SLOCK. - Actual plans, CPU/elapsed results, parameter declarations, assembly source, Linux distribution/kernel, and results from both affected CUs.
- The T-SQL control case showing that the contention is specific to the managed invocation path.
Microsoft documents Extended Events call stacks as the way to identify the operation acquiring a contended spinlock; interpreting the resulting internal stacks generally requires engine expertise and may require a support case.^4^
References
- Query hints (Transact-SQL)
- Performance of CLR integration architecture
- Handle large object (LOB) parameters in the CLR
- Diagnose and resolve spinlock contention on SQL Server
- Set trace flags with DBCC TRACEON (Transact-SQL)
- KB2887899 - FIX: Slow performance in SQL Server 2012 or SQL Server 2014 when you build an index on a spatial data type of a large table - SQL Server | Microsoft Support
- KB2896720 - FIX: Slow performance in SQL Server 2012 or SQL Server 2014 when you build an index on a spatial data type of a large table - SQL Server | Microsoft Support