{"id":45810,"date":"2026-07-27T14:07:11","date_gmt":"2026-07-27T12:07:11","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/?p=45810"},"modified":"2026-07-28T10:00:35","modified_gmt":"2026-07-28T08:00:35","slug":"split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/","title":{"rendered":"Split, Sort, Collapse: how SQL Server survives an overlapping unique update"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">One table, one single column, 10,000 contiguous values from 1 to 10,000. We shift everyone up by 1:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nUPDATE u SET val = val + 1;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Each new value lands on a value that already exists: <code>1<\/code> wants to become <code>2<\/code>, but a <code>2<\/code> is already there; <code>2<\/code> wants to become <code>3<\/code>, but a <code>3<\/code> is already there\u2026 Every target overlaps a neighboring value. Yet a unique index allows <strong>no duplicate, at any instant<\/strong>.<br>How can this update succeed?<\/p>\n\n\n\n<h2 id=\"h-two-tables-one-single-difference\" class=\"wp-block-heading\">Two tables, one single difference<\/h2>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\n-- Unique column\nCREATE TABLE u (val INT NOT NULL);\nCREATE UNIQUE INDEX ux_u ON u(val);\nINSERT INTO u (val)\n  SELECT TOP (10000) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))\n  FROM sys.all_objects a CROSS JOIN sys.all_objects b;\n\n-- Same column, without uniqueness\nCREATE TABLE n (val INT NOT NULL);\nINSERT INTO n (val) SELECT val FROM u;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">The same <code>UPDATE ... SET val = val + 1<\/code> on each. Yet the two execution plans differ completely: on <code>n<\/code>, a direct update, a single modification operator. On <code>u<\/code>, three unexpected operators appear: <strong>Split<\/strong>, <strong>Sort<\/strong>, <strong>Collapse<\/strong>. That is the entire gap between &#8220;any column&#8221; and &#8220;a unique column&#8221;.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"283\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-1-1-1024x283.png\" alt=\"\" class=\"wp-image-45812\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-1-1-1024x283.png 1024w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-1-1-300x83.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-1-1-768x212.png 768w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-1-1.png 1473w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 id=\"h-why-the-naive-method-doesn-t-work\" class=\"wp-block-heading\">Why the naive method doesn&#8217;t work<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s process <code>u<\/code> row by row, in ascending order. First row: <code>1 \u2192 2<\/code>. But <code>2<\/code> still exists. Two rows carry the value <code>2<\/code>: uniqueness is violated immediately. Processing in descending order would get by (<code>10000 \u2192 10001<\/code> first, then <code>9999 \u2192 10000<\/code>\u2026), but SQL Server can&#8217;t bet on the order in which the rows to process are acquired. It needs a method that works regardless of order, and that never lets the same value coexist twice.<\/p>\n\n\n\n<h2 id=\"h-split-sort-collapse\" class=\"wp-block-heading\">Split, sort, collapse<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is the engine&#8217;s answer, in three steps. Let&#8217;s take five rows with the values <code>3,4,5,6,7<\/code> and follow each step closely.<\/p>\n\n\n\n<h3 id=\"h-1-split-the-update-becomes-delete-insert\" class=\"wp-block-heading\">1. Split (the update becomes delete + insert)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Modifying the key of a unique index directly is risky: the target value may overlap a value that is present. Split works around the problem by decomposing each update into a <strong>deletion<\/strong> of the old value followed by an <strong>insertion<\/strong> of the new one. Our 5 rows become 10 operations:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nDELETE 3     (old value of row #0)\nINSERT 4     (new value of row #0)\nDELETE 4     (row #1)\nINSERT 5\nDELETE 5     (row #2)\nINSERT 6\nDELETE 6     (row #3)\nINSERT 7\nDELETE 7     (row #4)\nINSERT 8\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">A delete can never fail on uniqueness; an insert fails only if the final value is truly a duplicate. We&#8217;ve separated the two risks.<\/p>\n\n\n\n<h3 id=\"h-2-sort-sort-to-free-a-value-before-reoccupying-it\" class=\"wp-block-heading\">2. Sort (sort to free a value before reoccupying it)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The 10 operations are sorted by the index key. Decisive rule: for equal values, the <strong>delete comes before the insert<\/strong>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nDELETE 3\nDELETE 4     -- 4 is freed...\nINSERT 4     -- ...before being reoccupied\nDELETE 5\nINSERT 5\nDELETE 6\nINSERT 6\nDELETE 7\nINSERT 7\nINSERT 8\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This is where the overlap is defused. For each value, the old occupant leaves before the new one arrives. At no point do two rows share the same key.<\/p>\n\n\n\n<h3 id=\"h-3-collapse-reduce-the-intermediate-operations\" class=\"wp-block-heading\">3. Collapse (reduce the intermediate operations)<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">After sorting, each <code>DELETE k \/ INSERT k<\/code> pair for the same value sits adjacent. Collapse fuses each pair into a single in-place update of the existing index entry, rather than deleting and re-inserting it. The two unpaired ends survive as a real delete and a real insert.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nDELETE 3          (low end, no partner)\nMODIFY 4\nMODIFY 5\nMODIFY 6\nMODIFY 7\nINSERT 8          (high end, no partner)\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Does the engine really execute it this way? The transaction log settles it.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nSELECT Operation, Context, COUNT(*) AS n\nFROM sys.fn_dblog(NULL, NULL)\nWHERE AllocUnitName LIKE &#039;%ux_u%&#039;\nGROUP BY Operation, Context\nORDER BY n DESC;\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Result:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\nOperation            Context               n\nLOP_MODIFY_ROW       LCX_INDEX_LEAF        4\nLOP_DELETE_ROWS      LCX_MARK_AS_GHOST     1\nLOP_SET_BITS         LCX_PFS               1\nLOP_INSERT_ROWS      LCX_INDEX_LEAF        1\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">This result is particularly revealing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the five updates had truly been executed as five <code>DELETE<\/code>s followed by five <code>INSERT<\/code>s, we would have expected five deletions and five insertions in the log.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Yet what we ultimately observe is:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n4x MODIFY_ROW\n1x DELETE_ROWS\n1x INSERT_ROWS\n<\/pre><\/div>\n\n\n<p class=\"wp-block-paragraph\">Collapse is therefore not only a theoretical concept visible in the execution plan. The observations from <code>fn_dblog()<\/code> show that it translates concretely into a massive reduction of physical operations. The intermediate values are merged into simple index row modifications, while only the two ends of the shift survive as a genuine deletion (<code>3<\/code>) and a genuine insertion (<code>8<\/code>).<\/p>\n\n\n\n<h3 id=\"h-4-visualization-of-the-complete-split-sort-collapse-process\" class=\"wp-block-heading\">4. Visualization of the complete SPLIT-SORT-COLLAPSE process<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The preceding observations now make it possible to connect the theory to what is actually executed. The following visualization traces the complete sequence of the Split, Sort and Collapse phases, along with the progressive reduction of operations down to the final result observed in the transaction log:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"600\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/split-sort-collapse-animated.gif\" alt=\"\" class=\"wp-image-45848\" \/><\/figure>\n\n\n\n<h2 id=\"h-what-it-costs\" class=\"wp-block-heading\">What it costs<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>Split \/ Sort \/ Collapse<\/code> mechanism lets SQL Server guarantee uniqueness throughout the entire UPDATE, but this safety comes at a significant cost. To measure this impact, we ran exactly the same update on the two 10,000-row tables created earlier, with <code>STATISTICS IO ON<\/code> enabled. The results are unambiguous. On table u, SQL Server performed <strong>40,036<\/strong> logical reads, consumed 266 ms of CPU and 360 ms of elapsed time. On table n, the same operation required only <strong>34<\/strong> logical reads, 15 ms of CPU and 71 ms of elapsed time.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"272\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-12-1024x272.png\" alt=\"\" class=\"wp-image-45818\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-12-1024x272.png 1024w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-12-300x80.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-12-768x204.png 768w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-12-1536x408.png 1536w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-12.png 1613w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">It&#8217;s worth noting that this extra cost corresponds mainly to the logical processing imposed by the uniqueness guarantee. Indeed, our analysis with fn_dblog() shows that the engine does not naively delete and then reinsert each row. After Collapse, the intermediate operations are largely merged into simple MODIFY_ROW operations, which limits the physical work actually performed on the index pages. The price to pay is therefore not so much a full rebuild of the index as a substantial amount of preparatory organization that lets SQL Server guarantee that at no instant do two rows simultaneously hold the same unique key.<\/p>\n\n\n\n<h2 id=\"h-a-side-note-about-the-halloween-problem\" class=\"wp-block-heading\">A side note about the Halloween Problem<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This need to read everything before writing anything has a name. In the mid-1970s, Don Chamberlin, Pat Selinger and Morton Astrahan wrote a query meant to give a 10% raise to every employee earning under $25,000. It ran without error but left everyone at exactly $25,000: the engine scanned the salary index upward, and each raised row crossed the threshold, moved back ahead of the scan, and got raised again. They found it on Halloween, and the name stuck after the day, not the nature of the bug (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Halloween_Problem\" data-type=\"link\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Halloween_Problem\">link<\/a>).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Their fix was to make sure the optimizer never reads an update through an index built on the very column being updated. <code>Split\/Sort\/Collapse<\/code> is a descendant of that idea: when an <code>UPDATE<\/code> reads and writes the same index, reading and writing must be separated. That&#8217;s the Sort&#8217;s job. It is a <a href=\"https:\/\/www.oreilly.com\/library\/view\/learn-t-sql-querying\/9781789348811\/a531ee25-124c-492d-8641-b7fc0e3ab39e.xhtml\" data-type=\"link\" data-id=\"https:\/\/www.oreilly.com\/library\/view\/learn-t-sql-querying\/9781789348811\/a531ee25-124c-492d-8641-b7fc0e3ab39e.xhtml\"><strong>blocking<\/strong> operator<\/a>: it must consume its entire input before emitting a single row and that property forms the barrier. In doing so it <strong>materializes<\/strong> the whole set of rows to modify (in memory via a <em>memory grant<\/em> or spilling to tempdb if the volume exceeds it). Once that snapshot is frozen, each source row is read exactly once, and no write can ever catch up to it.<\/p>\n\n\n\n<h2 id=\"h-conclusion\" class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Updating a unique key that overlaps itself seems, at first glance, impossible without temporarily violating uniqueness. Yet, thanks to the Split \/ Sort \/ Collapse mechanism, SQL Server manages to turn a potentially conflicting operation into a sequence of actions that guarantees no duplicate ever appears at any instant. The execution plan analysis explains the logic the engine uses, while the study of the transaction log shows how this logic materializes concretely. The observations made with fn_dblog() reveal that the intermediate operations are largely reduced to MODIFY_ROW operations. In the end, the real complexity does not lie in the physical modifications themselves, but in the preparatory work needed to preserve uniqueness. That is precisely what explains the overhead observed compared to a classic update: SQL Server pays the price of safety and consistency, but then heavily optimizes the actual execution thanks to Collapse.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This post was inspired by <a href=\"https:\/\/www.linkedin.com\/in\/franckpachot\/\" data-type=\"link\" data-id=\"https:\/\/www.linkedin.com\/in\/franckpachot\/\">Franck Pachot<\/a>&#8216;s look at <a href=\"https:\/\/dev.to\/franckpachot\/following-rowids-through-an-oracle-unique-index-update-2lc\" data-type=\"link\" data-id=\"https:\/\/dev.to\/franckpachot\/following-rowids-through-an-oracle-unique-index-update-2lc\">the same problem on Oracle<\/a>, where he follows the ROWIDs through the index at the physical level. A good companion to this post, to read by the fireplace (or the air-con) !<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How SQL Server shifts a whole unique column by +1 without ever creating a duplicate using Split\/Sort\/Collapse.<\/p>\n","protected":false},"author":157,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":"","_members_access_role":[],"_members_access_error":""},"categories":[368,99],"tags":[876,2123,51],"type_dbi":[],"class_list":["post-45810","post","type-post","status-publish","format-standard","hentry","category-development-performance","category-sql-server","tag-constraint","tag-dml","tag-sql-server"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v28.0 (Yoast SEO v28.0) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Split, Sort, Collapse: how SQL Server survives an overlapping unique update - dbi Blog<\/title>\n<meta name=\"description\" content=\"How SQL Server shifts a whole unique column by +1 without ever creating a duplicate using Split\/Sort\/Collapse.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Split, Sort, Collapse: how SQL Server survives an overlapping unique update\" \/>\n<meta property=\"og:description\" content=\"How SQL Server shifts a whole unique column by +1 without ever creating a duplicate using Split\/Sort\/Collapse.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2026-07-27T12:07:11+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-07-28T08:00:35+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-1-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1473\" \/>\n\t<meta property=\"og:image:height\" content=\"407\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Louis Tochon\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Louis Tochon\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\\\/\"},\"author\":{\"name\":\"Louis Tochon\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/e4195b0cb120295b3407a502c23e75b6\"},\"headline\":\"Split, Sort, Collapse: how SQL Server survives an overlapping unique update\",\"datePublished\":\"2026-07-27T12:07:11+00:00\",\"dateModified\":\"2026-07-28T08:00:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\\\/\"},\"wordCount\":1138,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2026\\\/07\\\/image-1-1-1024x283.png\",\"keywords\":[\"Constraint\",\"dml\",\"SQL Server\"],\"articleSection\":[\"Development &amp; Performance\",\"SQL Server\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\\\/\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\\\/\",\"name\":\"Split, Sort, Collapse: how SQL Server survives an overlapping unique update - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2026\\\/07\\\/image-1-1-1024x283.png\",\"datePublished\":\"2026-07-27T12:07:11+00:00\",\"dateModified\":\"2026-07-28T08:00:35+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/e4195b0cb120295b3407a502c23e75b6\"},\"description\":\"How SQL Server shifts a whole unique column by +1 without ever creating a duplicate using Split\\\/Sort\\\/Collapse.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2026\\\/07\\\/image-1-1.png\",\"contentUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2026\\\/07\\\/image-1-1.png\",\"width\":1473,\"height\":407},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Split, Sort, Collapse: how SQL Server survives an overlapping unique update\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\",\"name\":\"dbi Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/e4195b0cb120295b3407a502c23e75b6\",\"name\":\"Louis Tochon\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ce0ee48c64e763e6c4076e21c80729d15bc4493288aeb8695125c69082100e10?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ce0ee48c64e763e6c4076e21c80729d15bc4493288aeb8695125c69082100e10?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/ce0ee48c64e763e6c4076e21c80729d15bc4493288aeb8695125c69082100e10?s=96&d=mm&r=g\",\"caption\":\"Louis Tochon\"},\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/author\\\/louistochon\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Split, Sort, Collapse: how SQL Server survives an overlapping unique update - dbi Blog","description":"How SQL Server shifts a whole unique column by +1 without ever creating a duplicate using Split\/Sort\/Collapse.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/","og_locale":"en_US","og_type":"article","og_title":"Split, Sort, Collapse: how SQL Server survives an overlapping unique update","og_description":"How SQL Server shifts a whole unique column by +1 without ever creating a duplicate using Split\/Sort\/Collapse.","og_url":"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/","og_site_name":"dbi Blog","article_published_time":"2026-07-27T12:07:11+00:00","article_modified_time":"2026-07-28T08:00:35+00:00","og_image":[{"width":1473,"height":407,"url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-1-1.png","type":"image\/png"}],"author":"Louis Tochon","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Louis Tochon","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/"},"author":{"name":"Louis Tochon","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/e4195b0cb120295b3407a502c23e75b6"},"headline":"Split, Sort, Collapse: how SQL Server survives an overlapping unique update","datePublished":"2026-07-27T12:07:11+00:00","dateModified":"2026-07-28T08:00:35+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/"},"wordCount":1138,"commentCount":0,"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-1-1-1024x283.png","keywords":["Constraint","dml","SQL Server"],"articleSection":["Development &amp; Performance","SQL Server"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/","url":"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/","name":"Split, Sort, Collapse: how SQL Server survives an overlapping unique update - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/#primaryimage"},"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-1-1-1024x283.png","datePublished":"2026-07-27T12:07:11+00:00","dateModified":"2026-07-28T08:00:35+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/e4195b0cb120295b3407a502c23e75b6"},"description":"How SQL Server shifts a whole unique column by +1 without ever creating a duplicate using Split\/Sort\/Collapse.","breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/#primaryimage","url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-1-1.png","contentUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2026\/07\/image-1-1.png","width":1473,"height":407},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/split-sort-collapse-how-sql-server-survives-an-overlapping-unique-update\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Split, Sort, Collapse: how SQL Server survives an overlapping unique update"}]},{"@type":"WebSite","@id":"https:\/\/www.dbi-services.com\/blog\/#website","url":"https:\/\/www.dbi-services.com\/blog\/","name":"dbi Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.dbi-services.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/e4195b0cb120295b3407a502c23e75b6","name":"Louis Tochon","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/ce0ee48c64e763e6c4076e21c80729d15bc4493288aeb8695125c69082100e10?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/ce0ee48c64e763e6c4076e21c80729d15bc4493288aeb8695125c69082100e10?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/ce0ee48c64e763e6c4076e21c80729d15bc4493288aeb8695125c69082100e10?s=96&d=mm&r=g","caption":"Louis Tochon"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/louistochon\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/45810","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/users\/157"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=45810"}],"version-history":[{"count":37,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/45810\/revisions"}],"predecessor-version":[{"id":45906,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/45810\/revisions\/45906"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=45810"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=45810"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=45810"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=45810"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}