{"id":7163,"date":"2016-02-26T08:55:38","date_gmt":"2016-02-26T07:55:38","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/"},"modified":"2016-02-26T08:55:38","modified_gmt":"2016-02-26T07:55:38","slug":"changing-an-existing-partition-configuration-well-not-so-easy","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/","title":{"rendered":"Changing an existing partition configuration &#8230; Well, not so easy!"},"content":{"rendered":"<p>This time let\u2019s talk about an interesting customer scenario where table partitioning was implemented on a table with 100 GB of data on SQL Server 2014. Partitioning in this context aimed to save disk space\u00a0 (archive data were compressed)\u00a0, help to reduce maintenance time and consumed resources as well (by using index and statistic maintenance operations on the\u00a0active partition).\u00a0 Finally, it will help to improve the queries performance on the concerned table that mainly focused on only the recent customer commands. Let&#8217;s say that it exists a few reporting queries that\u00a0 are designed to get older data for analysis. So the partition strategy was pretty simple: my customer decided to archive and compress data older than the year 2015 and leave recent records (since 2015) in the active partition. We implemented partitionning respectively only on the two filegroups ARCHIVE and PRIMARY because this implementation was supposed to be temporary and the estimated data growth small and steady. This first implementation was successful in terms of performance and manageability<\/p>\n<p>But of course this world is not perfect and the estimated size for the last year was higher than expected and my customer also wanted to archive data from last year in order to guarantee the application performance. In some ways, this is a good news because it means that we may guess that the business activity was better than expected but this is purely an assumption from my part \ud83d\ude42<\/p>\n<p>So let\u2019s go back to my customer need and in order to meet this new requirement, we have to deal with the existing partition strategy and this is not as simple as we may imagine because changing the existing partition boundaries may be an intensive resource and locking operation. In addition, my customer wants this operation to be as fast as possible to avoid blocking too long\u00a0his business activity. Let&#8217;s first to thank him because I know that almost of their requests are a challenging \ud83d\ude42<\/p>\n<p>Then let\u2019s demonstrate with this similar scenario that I implemented to my lab environment which includes a <em>bigTransactionHistory_stg<\/em> table in the adventureWorks2012 database with the following specification:<\/p>\n<pre class=\"brush: actionscript3; gutter: true; first-line: 1\">exec sp_spaceused 'dbo.bigtransactionhistory_stg'<\/pre>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-0-bigTransactionHistory-specs.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7198\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-0-bigTransactionHistory-specs.jpg\" alt=\"blog 80- 0 - bigTransactionHistory specs\" width=\"504\" height=\"46\" \/><\/a><\/p>\n<pre class=\"brush: actionscript3; gutter: true; first-line: 1\">exec sp_helpindex 'dbo.bigtransactionhistory_stg'<\/pre>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-0-bigTransactionHistory-specs-idx.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7199\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-0-bigTransactionHistory-specs-idx.jpg\" alt=\"blog 80- 0 - bigTransactionHistory specs idx\" width=\"610\" height=\"46\" \/><\/a><\/p>\n<p>My scenario does not include a very big table in size (1% of my customer&#8217;s data) but this is sufficient to point out the problems of changing an existing partition configuration.<\/p>\n<p>So let\u2019s begin by setting the scene: my table has a partitioned clustered index with the following information:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">SELECT\n       p.object_id,\n       o.name AS table_name,\n       p.partition_number,\n       p.rows,\n       au.total_pages,\n       au.total_pages \/ 128 AS total_size_mb,\n       au.type_desc,\n\t   p.data_compression_desc,\n       g.name AS [filegroup_name],\n       RVL.value AS left_range_boundary,\n       RVR.value AS right_range_boundary\n       --PF.[name], RV.boundary_id, RV.[value]\nFROM sys.partitions AS p (nolock)\n       LEFT JOIN sys.objects AS o (nolock)\n             ON o.object_id = p.object_id\n       LEFT JOIN sys.indexes i (nolock)\n\t\t\t ON p.object_id = i.object_id\n                    AND p.index_id = i.index_id\n       LEFT JOIN sys.allocation_units AS au (nolock)\n             ON p.hobt_id = au.container_id\n       LEFT JOIN sys.filegroups AS g (nolock)\n             ON g.data_space_id = au.data_space_id\n       LEFT JOIN sys.partition_schemes AS PS (nolock)\n             ON ps.data_space_id = i.data_space_id\n       LEFT JOIN sys.partition_functions AS PF (nolock)\n             ON PF.function_id = ps.function_id             \n       LEFT JOIN sys.partition_range_values AS RVL (nolock)\n             ON RVL.function_id = PF.function_id\n                    AND RVL.boundary_id + 1 = p.partition_number\n       LEFT JOIN sys.partition_range_values AS RVR (nolock)\n             ON RVL.function_id = PF.function_id\n                    AND RVR.boundary_id = p.partition_number\nWHERE p.object_id = object_id('bigtransactionhistory_stg')\n       AND p.index_id = 1\nORDER BY table_name, partition_number\nGO<\/pre>\n<p>&nbsp;<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-1-bigTransactionHistory-partition-initial.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7200 size-large\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-1-bigTransactionHistory-partition-initial.jpg\" alt=\"blog 80- 1 - bigTransactionHistory partition initial\" width=\"1024\" height=\"55\" \/><\/a><\/p>\n<p>As expected you may notice a simple partitioning stuff with only two partitions based on right range boundary:<\/p>\n<ul>\n<li>ARCHIVE partition (ARCHIVE filegroup) includes records older than 01\/01\/2015. This partition is page compressed.<\/li>\n<li>Current partition (PRIMARY filegroup) contains recent records from the year 2015.<\/li>\n<\/ul>\n<p>Go ahead and let\u2019s try to achieve the task of reorganizing correctly the current partition strategy in order to meet my customer scenario. The high level expected outcome is as follows:<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-1-expected-partitionning-result.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7201\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-1-expected-partitionning-result.jpg\" alt=\"blog 80- 1 - expected partitionning result\" width=\"432\" height=\"58\" \/><\/a><\/p>\n<p>We want to dedicate one partition per year since 2015 and anticipate data growth. So we have to add three partitions FG2015, FG2016 for existing data and FG2017 that will be empty for now but we want to anticipate and avoid data movement scenario from any potential split scenario (according to the Microsoft documentation<a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms186307.aspx\" target=\"_blank\" rel=\"noopener noreferrer\"> here<\/a>).<\/p>\n<p>Now the picture of the starting scenario:<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-21-bigTransactionHistory-1-init.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7202\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-21-bigTransactionHistory-1-init.jpg\" alt=\"blog 80- 21 - bigTransactionHistory 1 - init\" width=\"242\" height=\"136\" \/><\/a><\/p>\n<p>At this point I may see two strategies. Let\u2019s begin with the first one that is probably the most simple (and intuitive):<\/p>\n<p>Firstly, in order to reorganize correctly the current partition configuration we have no choice and we have to exclude the primary filegroup for the partition strategy, so the game will consists in merging data from the primary filegroup with the ARCHIVE partition.<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-22-bigTransactionHistory-1-drop-primary.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7203\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-22-bigTransactionHistory-1-drop-primary.jpg\" alt=\"blog 80- 22 - bigTransactionHistory 1 - drop primary\" width=\"237\" height=\"115\" \/><\/a><\/p>\n<p>Then we will have to add consecutively two filegroups FG2015 and FG2016 and move related data from the ARCHIVE partition to their respective partitions.<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-23-bigTransactionHistory-1-new-partitions.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7204\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-23-bigTransactionHistory-1-new-partitions.jpg\" alt=\"blog 80- 23 - bigTransactionHistory 1 - new partitions\" width=\"324\" height=\"174\" \/><\/a><\/p>\n<p>And finally add the last empty partition FG2017.<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-24-bigTransactionHistory-1-last-empty-partition.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7205\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-24-bigTransactionHistory-1-last-empty-partition.jpg\" alt=\"blog 80- 24 - bigTransactionHistory 1 - last empty partition\" width=\"432\" height=\"130\" \/><\/a><\/p>\n<p>The main drawback with this strategy is that it incurs data movement that may be a time and resource consuming operation. In this configuration, we have to split partition that already contain data. You can refer to the interesting article of David Peter Hansen <a href=\"http:\/\/davidpeter.org\/sql-server-partition-split-data-movement\/\" target=\"_blank\" rel=\"noopener noreferrer\">here<\/a> about data movement and split operation. This is the same story with the first MERGE operation here because as stated to Microsoft documentation<a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/ms186307.aspx\" target=\"_blank\" rel=\"noopener noreferrer\"> here<\/a>, merging a partition means dropping the partition with the concerned boundary point and moving data to other one.<\/p>\n<p>Here the T-SQL script to simulate this first strategy:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">-- STEP MERGE\nUSE AdventureWorks2012;\nGO\n\nALTER PARTITION FUNCTION BigTransactionRange()\nMERGE RANGE(N'2015-01-01T00:00:00.000');\nGO\n\n\n-- STEP SPLIT (2015)\nALTER DATABASE [AdventureWorks2012] \nADD FILEGROUP [FG2015]\nGO\n\nALTER DATABASE [AdventureWorks2012] \nADD FILE ( NAME = N'FG2015', FILENAME = N'E:\\SQLSERVER\\INST14\\DATA\\AdventureWorks2012_2015.ndf' , SIZE = 1024KB , FILEGROWTH = 1024KB ) \nTO FILEGROUP [FG2015] \nGO\n\nALTER PARTITION SCHEME TransactionsPS1 NEXT USED [FG2015];\nGO\n\nALTER PARTITION FUNCTION BigTransactionRange()\nSPLIT RANGE(N'2015-01-01T00:00:00.000');\nGO\n\n\n-- STEP SPLIT (2016)\nALTER DATABASE [AdventureWorks2012] \nADD FILEGROUP [FG2016]\nGO\nALTER DATABASE [AdventureWorks2012] \nADD FILE ( NAME = N'FG2016', FILENAME = N'E:\\SQLSERVER\\INST14\\DATA\\AdventureWorks2012_2016.ndf' , SIZE = 1024KB , FILEGROWTH = 1024KB ) \nTO FILEGROUP [FG2016] \nGO\n\nALTER PARTITION SCHEME TransactionsPS1 NEXT USED [FG2016];\nGO\n\nALTER PARTITION FUNCTION BigTransactionRange()\nSPLIT RANGE(N'2016-01-01T00:00:00.000');\nGO\n\n-- STEP SPLIZ (2007)\nALTER DATABASE [AdventureWorks2012] \nADD FILEGROUP [FG2017]\nGO\nALTER DATABASE [AdventureWorks2012] \nADD FILE ( NAME = N'FG2017', FILENAME = N'E:\\SQLSERVER\\INST14\\DATA\\AdventureWorks2012_2017.ndf' , SIZE = 1024KB , FILEGROWTH = 1024KB ) \nTO FILEGROUP [FG2017] \nGO\n\nALTER PARTITION SCHEME TransactionsPS1 NEXT USED [FG2017];\nGO<\/pre>\n<p>&nbsp;<\/p>\n<p>The following table describes each step of this strategy, their duration and the amount of records related to data movement in this case (LOP_INSERT_ROWS and LOP_DELETE_ROWS). Data movement are fully logged in the transaction log. Otherwise, there are other entries related in the transaction log but they are less relevant in this context and we want to focus only on the data movement stuff. However, let\u2019s say that in the case of the MERGE operation, additional interesting entries type as LOP_COMPRESSION_INFO exist in the transaction log because the ARCHIVE partition is page-based compressed.<\/p>\n<table>\n<tbody>\n<tr>\n<td width=\"151\"><strong>Step<\/strong><\/td>\n<td width=\"151\"><strong>Duration <\/strong><\/td>\n<td width=\"151\"><strong>LOP_INSERT_ROWS<\/strong><\/td>\n<td width=\"151\"><strong>LOP_DELETE_ROWS<\/strong><\/td>\n<\/tr>\n<tr>\n<td width=\"151\"><strong>MERGE<\/strong><\/td>\n<td width=\"151\">00:01:49<\/td>\n<td width=\"151\">8328657<\/td>\n<td width=\"151\"><\/td>\n<\/tr>\n<tr>\n<td width=\"151\"><strong>SPLIT (2015)<\/strong><\/td>\n<td width=\"151\">00:02:44<\/td>\n<td width=\"151\">8361367<\/td>\n<td width=\"151\">8361248<\/td>\n<\/tr>\n<tr>\n<td width=\"151\"><strong>SPLIT (2016)<\/strong><\/td>\n<td width=\"151\">00:01:02<\/td>\n<td width=\"151\">3213023<\/td>\n<td width=\"151\">3212971<\/td>\n<\/tr>\n<tr>\n<td width=\"151\"><strong>SPLIT (2017)<\/strong><\/td>\n<td width=\"151\">00:00:00<\/td>\n<td width=\"151\">&#8211;<\/td>\n<td width=\"151\">&#8211;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p>An extra step is required in our case because all data came from the ARCHIVE partition and are compressed by default. This is an expected behaviour for the partition FG2015 but we have to inhibit the compression stuff for the current partition FG2016. In my case, the duration of the rebuild operation took 13 seconds.<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">ALTER INDEX [idx_bigtransactionhistory_transactiondate]\nON [dbo].[bigTransactionHistory_stg]\nREBUILD PARTITION = 3 WITH (DATA_COMPRESSION = NONE);\nGO<\/pre>\n<p>So we finally reach out the expected outcome as shown below:<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-25-bigTransactionHistory-1-outcome.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7206 size-large\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-25-bigTransactionHistory-1-outcome.jpg\" alt=\"blog 80- 25 - bigTransactionHistory 1 - outcome\" width=\"1024\" height=\"77\" \/><\/a><\/p>\n<p>At this first glance, the above strategy is probably not suitable for my customer because in his case, the duration and resources taken by each operation would be in a different order of magnitude and one of his requirement is that operation should be as fast as possible. After all, I only tested with 1% of the total of real customer data.<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-3-jeu-du-taquin.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright wp-image-7208 size-thumbnail\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-3-jeu-du-taquin.jpg\" alt=\"blog 80- 3 - jeu du taquin\" width=\"150\" height=\"150\" \/><\/a>This is why we have find out a different strategy to address this data movement phenomena. For that, we have to think differently how we can move data from one partition to other and this is where what I call the \u201cjeu du taquin\u201d based strategy comes into play and based on the SWITCH feature of the partitions.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>Let\u2019s apply the same principle to our context now let\u2019s introduce an additional piece in the game: an additional table named bigTransactionHistory_stg_temp created on the PRIMARY filegroup that will serve to store temporary recent data (&gt;= 2015) from the bigTransactionHistory_stg partitioned table. To achieve this task we may relay on the SWITCH command which is only a metadata operation that means no data movement in this case.<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-40-bitransactionhstory-2-move-primary.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7211\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-40-bitransactionhstory-2-move-primary.jpg\" alt=\"blog 80- 40- bitransactionhstory 2 - move primary\" width=\"424\" height=\"226\" \/><\/a><\/p>\n<p>And this is the secret sauce here! Indeed, we are free to work on our partitioned table and prepare the new concerned right range boundaries without suffering data movement because the primary partition is empty!<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-41-bitransactionhstory-2-drop-primary.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7212\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-41-bitransactionhstory-2-drop-primary.jpg\" alt=\"blog 80- 41- bitransactionhstory 2 - drop primary\" width=\"424\" height=\"226\" \/><\/a><\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-42-bitransactionhstory-2-new-partitions.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7213\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-42-bitransactionhstory-2-new-partitions.jpg\" alt=\"blog 80- 42- bitransactionhstory 2 - new partitions\" width=\"434\" height=\"252\" \/><\/a><\/p>\n<p>At this point no data movement has occurred but the game becomes more complicated here because we have to redistribute data from the <em>bigTransactionHistory_stg_temp<\/em> table into new partitions FG2015 and FG2016. As a reminder, my temporary table is not partitioned, so we can\u2019t benefit anymore from partitioning features but we may do other interesting things. Here my proposal: we may create two staging tables respectively on the FG2015 and FG2016 filegroups and then load data from the temporary table into the two staging tables in parallel. Finally, we may use the SWITCH partition feature in order to move quickly data from the staging table into the <em>bigTransactionHistory_stg<\/em> partitioned table.<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-43-bitransactionhstory-2-bulk-load-staging-tables.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7215\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-43-bitransactionhstory-2-bulk-load-staging-tables.jpg\" alt=\"blog 80- 43- bitransactionhstory 2 - bulk load staging tables\" width=\"608\" height=\"390\" \/><\/a><\/p>\n<p>Before switching partitions from the staging tables to the final partitioned tables, we must before implement check constraints on the formers in order to guarantee to the optimizer that the concerned partitions don\u2019t contain any value outside their boundaries.<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-44-bitransactionhstory-2-switch-partitionss.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7216\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-44-bitransactionhstory-2-switch-partitionss.jpg\" alt=\"blog 80- 44- bitransactionhstory 2 - switch partitionss\" width=\"608\" height=\"246\" \/><\/a><\/p>\n<p>To finally reach out the expected outcome:<\/p>\n<p><a href=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-24-bigTransactionHistory-1-last-empty-partition.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-7205\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-24-bigTransactionHistory-1-last-empty-partition.jpg\" alt=\"blog 80- 24 - bigTransactionHistory 1 - last empty partition\" width=\"432\" height=\"130\" \/><\/a><\/p>\n<p>Here the T-SQL script to simulate this second partition strategy:<\/p>\n<pre class=\"brush: sql; gutter: true; first-line: 1\">USE [AdventureWorks2012]\nGO\n\n\nCREATE TABLE [dbo].[bigTransactionHistory_stg_temp](\n\t[TransactionID] [int] NULL,\n\t[ProductID] [int] NOT NULL,\n\t[TransactionDate] [datetime] NULL,\n\t[Quantity] [int] NULL,\n\t[ActualCost] [money] NULL,\n\t[status] [bit] NULL\n)\nON [PRIMARY]\nGO\n \n-- Create temporary table to store recent data\nCREATE CLUSTERED INDEX [idx_bigtransactionhistory_transactiondate_temp] \nON [dbo].[bigTransactionHistory_stg_temp]\n(\n\t[TransactionDate] ASC,\n\t[TransactionID] ASC\n)\nON [PRIMARY]\n\n\n-- SWITCH data from the bigTransactionHistory_stg table (primary filegroup) \n-- to the bigTransactionHistory_stg_temp table (primary filegroup)\nALTER TABLE [dbo].[bigTransactionHistory_stg]\nSWITCH PARTITION 2 TO [dbo].[bigTransactionHistory_stg_temp] \nGO\n\n\n-- Get rid of the primary partition by merging the year 2015 boundary\nALTER PARTITION FUNCTION BigTransactionRange()\nMERGE RANGE(N'2015-01-01T00:00:00.000');\nGO\n\n-- Preparation of new partitions\nALTER DATABASE [AdventureWorks2012] \nADD FILEGROUP [FG2015]\nGO\nALTER DATABASE [AdventureWorks2012] \nADD FILE ( NAME = N'FG2015', FILENAME = N'E:\\SQLSERVER\\INST14\\DATA\\AdventureWorks2012_2015.ndf' , SIZE = 1048KB , FILEGROWTH = 1024KB ) \nTO FILEGROUP [FG2015] \nGO \n\nALTER DATABASE [AdventureWorks2012] \nADD FILEGROUP [FG2017]\nGO\nALTER DATABASE [AdventureWorks2012] \nADD FILE ( NAME = N'FG2017', FILENAME = N'E:\\SQLSERVER\\INST14\\DATA\\AdventureWorks2012_2017.ndf' , SIZE = 1048KB , FILEGROWTH = 1024KB ) \nTO FILEGROUP [FG2017] \nGO \n\nALTER DATABASE [AdventureWorks2012] \nADD FILEGROUP [FG2016]\nGO\nALTER DATABASE [AdventureWorks2012] \nADD FILE ( NAME = N'FG2016', FILENAME = N'E:\\SQLSERVER\\INST14\\DATA\\AdventureWorks2012_2016.ndf' , SIZE = 1048KB , FILEGROWTH = 1024KB ) \nTO FILEGROUP [FG2016] \nGO \n\n\n-- create new boundary 2015 --&gt; FG2015\nALTER PARTITION SCHEME TransactionsPS1 NEXT USED [FG2015];\nGO\n\nALTER PARTITION FUNCTION BigTransactionRange()\nSPLIT RANGE (N'2015-01-01T00:00:00.000');\nGO\n\n-- create new boundary 2016 --&gt; FG2016\nALTER PARTITION SCHEME TransactionsPS1 NEXT USED [FG2016];\nGO\n\nALTER PARTITION FUNCTION BigTransactionRange()\nSPLIT RANGE (N'2016-01-01T00:00:00.000');\nGO\n\n-- Split range with new boundary 2017 --&gt; FG2017\nALTER PARTITION SCHEME TransactionsPS1 NEXT USED [FG2017];\nGO\n\nALTER PARTITION FUNCTION BigTransactionRange()\nSPLIT RANGE (N'2017-01-01T00:00:00.000');\nGO\n\n-- current (FG2016) and next partition (FG2017) are not compressed\nALTER INDEX [idx_bigtransactionhistory_transactiondate]\nON [dbo].[bigTransactionHistory_stg]\nREBUILD PARTITION = 3 WITH (DATA_COMPRESSION = NONE);\nGO\n\nALTER INDEX [idx_bigtransactionhistory_transactiondate]\nON [dbo].[bigTransactionHistory_stg]\nREBUILD PARTITION = 4 WITH (DATA_COMPRESSION = NONE);\nGO\n\n\n-- Create staging tables\nCREATE TABLE [dbo].[bigTransactionHistory_stg_2015](\n\t[TransactionID] [int] NULL,\n\t[ProductID] [int] NOT NULL,\n\t[TransactionDate] [datetime] NULL,\n\t[Quantity] [int] NULL,\n\t[ActualCost] [money] NULL,\n\t[status] [bit] NULL\n)\nON [FG2015]\nGO\n\nCREATE CLUSTERED INDEX [idx_bigtransactionhistory_transactiondate_2015] \nON [dbo].[bigTransactionHistory_stg_2015]\n(\n\t[TransactionDate] ASC,\n\t[TransactionID] ASC\n)\nWITH (DATA_COMPRESSION = PAGE)\nON [FG2015]\nGO\n\n\nCREATE TABLE [dbo].[bigTransactionHistory_stg_2016](\n\t[TransactionID] [int] NULL,\n\t[ProductID] [int] NOT NULL,\n\t[TransactionDate] [datetime] NULL,\n\t[Quantity] [int] NULL,\n\t[ActualCost] [money] NULL,\n\t[status] [bit] NULL\n)\nON [FG2016]\nGO\n\nCREATE CLUSTERED INDEX [idx_bigtransactionhistory_transactiondate_2016] \nON [dbo].[bigTransactionHistory_stg_2016]\n(\n\t[TransactionDate] ASC,\n\t[TransactionID] ASC\n)\nON [FG2016]\nGO\n\n\n-- Load data into staging tables\nINSERT INTO dbo.bigTransactionHistory_stg_2016 WITH (TABLOCK)\n([TransactionID], [ProductID], [TransactionDate], [Quantity], [ActualCost], [status])\nSELECT \n\t[TransactionID], [ProductID], [TransactionDate], [Quantity], [ActualCost], [status]\nFROM [dbo].[bigTransactionHistory_stg_temp] \nWHERE TransactionDate &gt;= '20160101';\nGO\n\nINSERT INTO dbo.bigTransactionHistory_stg_2015 WITH (TABLOCK)\n([TransactionID], [ProductID], [TransactionDate], [Quantity], [ActualCost], [status])\nSELECT \n\t[TransactionID], [ProductID], [TransactionDate], [Quantity], [ActualCost], [status]\nFROM [dbo].[bigTransactionHistory_stg_temp] \nWHERE TransactionDate &gt;= '20150101' AND TransactionDate &lt; '20160101';\nGO\n\n-- Add check constraint to the staging tables before switching to the partitionned tables\nALTER TABLE dbo.bigTransactionHistory_stg_2015\nADD CONSTRAINT CHK CHECK (TransactionDate BETWEEN '20150101 00:00:00.000' AND '20151231 23:59:59.997' AND TransactionDate IS NOT NULL)\n\nALTER TABLE dbo.bigTransactionHistory_stg_2016\nADD CONSTRAINT CHK_2016 CHECK (TransactionDate BETWEEN '20160101 00:00:00.000' AND '20161231 23:59:59.997' AND TransactionDate IS NOT NULL)\nGO\n\nALTER TABLE [dbo].[bigTransactionHistory_stg_2015]\nSWITCH TO [dbo].[bigTransactionHistory_stg] PARTITION 2\n\nALTER TABLE [dbo].[bigTransactionHistory_stg_2016]\nSWITCH TO [dbo].[bigTransactionHistory_stg] PARTITION 3\n\n--DROP TABLE [dbo].[bigTransactionHistory_stg_temp];\n--DROP TABLE [dbo].[bigTransactionHistory_stg_2015]\n--DROP TABLE [dbo].[bigTransactionHistory_stg_2016]<\/pre>\n<p>Yes, I admit this is a more sophisticated process here but trust me this is the much more efficient in terms of performance because it includes only one real data movement during all the steps compared to the first strategy. In my case, executing the above script took roughly 40s, so 88% of improvement &#8230; not so bad \ud83d\ude42<\/p>\n<p>Happy partitioning!<\/p>\n<p>By David Barbarin<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This time let\u2019s talk about an interesting customer scenario where table partitioning was implemented on a table with 100 GB of data on SQL Server 2014. Partitioning in this context aimed to save disk space\u00a0 (archive data were compressed)\u00a0, help to reduce maintenance time and consumed resources as well (by using index and statistic maintenance [&hellip;]<\/p>\n","protected":false},"author":26,"featured_media":7179,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[368],"tags":[751,752,366,67,753,51,754],"type_dbi":[],"class_list":["post-7163","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-development-performance","tag-data-movement","tag-merge","tag-partitioning","tag-performance","tag-split","tag-sql-server","tag-switch"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.2) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Changing an existing partition configuration ... Well, not so easy!<\/title>\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\/changing-an-existing-partition-configuration-well-not-so-easy\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Changing an existing partition configuration ... Well, not so easy!\" \/>\n<meta property=\"og:description\" content=\"This time let\u2019s talk about an interesting customer scenario where table partitioning was implemented on a table with 100 GB of data on SQL Server 2014. Partitioning in this context aimed to save disk space\u00a0 (archive data were compressed)\u00a0, help to reduce maintenance time and consumed resources as well (by using index and statistic maintenance [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2016-02-26T07:55:38+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-0-bigTransactionHistory-specs-1.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"504\" \/>\n\t<meta property=\"og:image:height\" content=\"46\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Microsoft Team\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Microsoft Team\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 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\/changing-an-existing-partition-configuration-well-not-so-easy\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/\"},\"author\":{\"name\":\"Microsoft Team\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/bfab48333280d616e1170e7369df90a4\"},\"headline\":\"Changing an existing partition configuration &#8230; Well, not so easy!\",\"datePublished\":\"2016-02-26T07:55:38+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/\"},\"wordCount\":1383,\"commentCount\":0,\"image\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-0-bigTransactionHistory-specs-1.jpg\",\"keywords\":[\"Data movement\",\"MERGE\",\"Partitioning\",\"Performance\",\"SPLIT\",\"SQL Server\",\"SWITCH\"],\"articleSection\":[\"Development &amp; Performance\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/\",\"name\":\"Changing an existing partition configuration ... Well, not so easy!\",\"isPartOf\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-0-bigTransactionHistory-specs-1.jpg\",\"datePublished\":\"2016-02-26T07:55:38+00:00\",\"author\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/bfab48333280d616e1170e7369df90a4\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/#primaryimage\",\"url\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-0-bigTransactionHistory-specs-1.jpg\",\"contentUrl\":\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-0-bigTransactionHistory-specs-1.jpg\",\"width\":504,\"height\":46},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/www.dbi-services.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Changing an existing partition configuration &#8230; Well, not so easy!\"}]},{\"@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\/bfab48333280d616e1170e7369df90a4\",\"name\":\"Microsoft Team\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/c44a1a792c059f24055763aa77d80a244467f6eef724a8bd13db8d4a350b7a4c?s=96&d=mm&r=g\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c44a1a792c059f24055763aa77d80a244467f6eef724a8bd13db8d4a350b7a4c?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c44a1a792c059f24055763aa77d80a244467f6eef724a8bd13db8d4a350b7a4c?s=96&d=mm&r=g\",\"caption\":\"Microsoft Team\"},\"url\":\"https:\/\/www.dbi-services.com\/blog\/author\/microsoft-team\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Changing an existing partition configuration ... Well, not so easy!","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\/changing-an-existing-partition-configuration-well-not-so-easy\/","og_locale":"en_US","og_type":"article","og_title":"Changing an existing partition configuration ... Well, not so easy!","og_description":"This time let\u2019s talk about an interesting customer scenario where table partitioning was implemented on a table with 100 GB of data on SQL Server 2014. Partitioning in this context aimed to save disk space\u00a0 (archive data were compressed)\u00a0, help to reduce maintenance time and consumed resources as well (by using index and statistic maintenance [&hellip;]","og_url":"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/","og_site_name":"dbi Blog","article_published_time":"2016-02-26T07:55:38+00:00","og_image":[{"width":504,"height":46,"url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-0-bigTransactionHistory-specs-1.jpg","type":"image\/jpeg"}],"author":"Microsoft Team","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Microsoft Team","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/"},"author":{"name":"Microsoft Team","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/bfab48333280d616e1170e7369df90a4"},"headline":"Changing an existing partition configuration &#8230; Well, not so easy!","datePublished":"2016-02-26T07:55:38+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/"},"wordCount":1383,"commentCount":0,"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-0-bigTransactionHistory-specs-1.jpg","keywords":["Data movement","MERGE","Partitioning","Performance","SPLIT","SQL Server","SWITCH"],"articleSection":["Development &amp; Performance"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/","url":"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/","name":"Changing an existing partition configuration ... Well, not so easy!","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/#primaryimage"},"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-0-bigTransactionHistory-specs-1.jpg","datePublished":"2016-02-26T07:55:38+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/bfab48333280d616e1170e7369df90a4"},"breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/#primaryimage","url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-0-bigTransactionHistory-specs-1.jpg","contentUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2022\/04\/blog-80-0-bigTransactionHistory-specs-1.jpg","width":504,"height":46},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/changing-an-existing-partition-configuration-well-not-so-easy\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Changing an existing partition configuration &#8230; Well, not so easy!"}]},{"@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\/bfab48333280d616e1170e7369df90a4","name":"Microsoft Team","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/c44a1a792c059f24055763aa77d80a244467f6eef724a8bd13db8d4a350b7a4c?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/c44a1a792c059f24055763aa77d80a244467f6eef724a8bd13db8d4a350b7a4c?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c44a1a792c059f24055763aa77d80a244467f6eef724a8bd13db8d4a350b7a4c?s=96&d=mm&r=g","caption":"Microsoft Team"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/microsoft-team\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/7163","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\/26"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=7163"}],"version-history":[{"count":0,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/7163\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media\/7179"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=7163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=7163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=7163"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=7163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}