{"id":31316,"date":"2024-02-26T17:59:52","date_gmt":"2024-02-26T16:59:52","guid":{"rendered":"https:\/\/www.dbi-services.com\/blog\/?p=31316"},"modified":"2024-02-26T17:59:55","modified_gmt":"2024-02-26T16:59:55","slug":"sql-server-manage-large-data-ranges-using-partitioning","status":"publish","type":"post","link":"https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/","title":{"rendered":"SQL Server: Manage large data ranges using partitioning"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"h-introduction\"><strong>Introduction:\u00a0<\/strong><\/h2>\n\n\n\n<p>When it comes  to moving ranges of data with many rows across different tables in SQL-Server, the partitioning functionality of SQL-Server can provide a good solution for manageability and performance optimizing. In this blog we will look at the different advantages and the concept of partitioning in SQL-Server.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-concept-overview\"><strong>Concept overview:\u00a0<\/strong><\/h2>\n\n\n\n<p>In SQL-Server, partitioning can divide the data of an index or table into smaller units. These units are called partitions. For that purpose, every row is assigned to a range and every range in turn is assigned to a specific partition. Practically there are two main components: The partition function and the partition scheme.&nbsp;&nbsp;<\/p>\n\n\n\n<p>The partition function defines the range borders through boundary values and thus the number of partitions, in consideration with the data values, as well. You can define a partition function either as \u201crange right\u201d or \u201crange left\u201d. The main difference is how the boundary value gets treated. In a range right partition function, the boundary value is the <strong>first<\/strong> value of the <strong>next<\/strong> partition while in a range left partition function the boundary value is the <strong>last<\/strong> value of the <strong>previous<\/strong> partition. For example:&nbsp;<\/p>\n\n\n\n<p>We want to partition a table by year and the datatype of the column where we want to apply the partition function has the datatype \u201cdate\u201d. Totally we have entries for the year 2023 and 2024 which means, we want 2x partitions. In a range right function, the boundary value must be the first day of the year 2024 whereas in a range left function the boundary value must be the last day of the year 2023.\u00a0\u00a0<\/p>\n\n\n\n<p>See example below:\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-style-default\"><img loading=\"lazy\" decoding=\"async\" width=\"331\" height=\"66\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-43.png\" alt=\"Image: Partition right\" class=\"wp-image-31317\" title=\"\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-43.png 331w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-43-300x60.png 300w\" sizes=\"auto, (max-width: 331px) 100vw, 331px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"319\" height=\"60\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-44.png\" alt=\"Image: Partition left\" class=\"wp-image-31318\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-44.png 319w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-44-300x56.png 300w\" sizes=\"auto, (max-width: 319px) 100vw, 319px\" \/><\/figure>\n\n\n\n<p>The partition scheme is used to map the different partitions, which are defined through the partition function, to multiple or one filegroup.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-main-benefits-of-partitioning\"><strong>Main benefits of partitioning<\/strong>:<\/h2>\n\n\n\n<p>There are multiple scenarios where performance or manageability of a data model can be increased through partitioning. The main advantage of partitioning is that it reduces the contention on the whole table as a database object and restricts it to the partition level when performing operations on the corresponding data range. Partitioning also facilitates data transfer with the \u201cswitch partition\u201d statement, this statement performs a switch-in or switch-out of o whole partition. Through that, a large amount of data can be transferred very quickly.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-demo-lab\"><strong>Demo Lab<\/strong>:<\/h2>\n\n\n\n<p>For demo purposes I created the following script, which will create three tables with 5 million rows of historical data from 11 years in the past until today:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nUSE &#x5B;master] \nGO \n \n--Create Test Database \nCREATE DATABASE &#x5B;TestPartition] \nGO \n \n--Change Recovery Model \nALTER DATABASE &#x5B;TestPartition] SET RECOVERY SIMPLE WITH NO_WAIT \nGO \n \n--Create Tables \nUse &#x5B;TestPartition] \nGO \n \nCREATE TABLE &#x5B;dbo].&#x5B;Table01_HEAP]( \n&#x5B;Entry_Datetime] &#x5B;datetime] NOT NULL, \n&#x5B;Entry_Text] &#x5B;nvarchar](50) NULL \n) \nGO \n \nCREATE TABLE &#x5B;dbo].&#x5B;Table01_CLUSTEREDINDEX]( \n&#x5B;Entry_Datetime] &#x5B;datetime] NOT NULL, \n&#x5B;Entry_Text] &#x5B;nvarchar](50) NULL \n) \nGO \n \nCREATE TABLE &#x5B;dbo].&#x5B;Table01_PARTITIONED]( \n&#x5B;Entry_Datetime] &#x5B;datetime] NOT NULL, \n&#x5B;Entry_Text] &#x5B;nvarchar](50) NULL \n) \nGO \n \n--GENERATE DATA \n \ndeclare @date as datetime \n \ndeclare @YearSubtract int \ndeclare @DaySubtract int \ndeclare @HourSubtract int \ndeclare @MinuteSubtract int  \ndeclare @SecondSubtract int  \ndeclare @MilliSubtract int \n \n--Specifiy how many Years backwards data should be generated \ndeclare @YearsBackward int \nset @YearsBackward = 11 \n \n--Specifiy how many rows of data should be generated \ndeclare @rows2generate int \nset @rows2generate = 5000000 \n \n \ndeclare @counter int \nset @counter = 1 \n \n--generate data entries \nwhile @counter &lt;= @rows2generate  \nbegin \n \n--Year \nSet @YearSubtract = floor(rand() * (@YearsBackward - 0 + 1)) + 0 \n--Day \nSet @DaySubtract = floor(rand() * (365 - 0 + 1)) + 0 \n--Hour \nSet @HourSubtract = floor(rand() * (24 - 0 + 1)) + 0 \n--Minute \nSet @MinuteSubtract = floor(rand() * (60 - 0 + 1)) + 0 \n--Second \nSet @SecondSubtract = floor(rand() * (60 - 0 + 1)) + 0 \n--Milisecond \nSet @MilliSubtract = floor(rand() * (1000 - 0 + 1)) + 0 \n \n \nset @date = Dateadd(YEAR, -@YearSubtract , Getdate()) \nset @date = Dateadd(DAY, -@DaySubtract , @date) \nset @date = Dateadd(HOUR, -@HourSubtract , @date) \nset @date = Dateadd(MINUTE, -@MinuteSubtract , @date) \nset @date = Dateadd(SECOND, -@SecondSubtract , @date) \nset @date = Dateadd(MILLISECOND, @MilliSubtract , @date) \n \ninsert into Table01_HEAP (Entry_Datetime, Entry_Text) \nValues (@date, &#039;This is a entry from &#039; + convert(nvarchar, @date, 29)) \n \nset @counter = @counter + 1 \n \nend \n \n--COPY DATA TO OTHER TABLES \n \nINSERT INTO dbo.Table01_CLUSTEREDINDEX \n  (Entry_Datetime, Entry_Text) \nSELECT Entry_Datetime, Entry_Text \n  FROM Table01_HEAP \n \nINSERT INTO dbo.Table01_PARTITIONED \n  (Entry_Datetime, Entry_Text) \nSELECT Entry_Datetime, Entry_Text \n  FROM Table01_HEAP \n \n--Create Clustered Indexes for dbo.Table01_CLUSTEREDINDEX and dbo.Table01_PARTITIONED \n \nCREATE CLUSTERED INDEX &#x5B;ClusteredIndex_Table01_CLUSTEREDINDEX] ON &#x5B;dbo].&#x5B;Table01_CLUSTEREDINDEX] \n( \n&#x5B;Entry_Datetime] ASC \n \n) on &#x5B;PRIMARY] \nGO \n \nCREATE CLUSTERED INDEX &#x5B;ClusteredIndex_Table01_PARTITIONED] ON &#x5B;dbo].&#x5B;Table01_PARTITIONED] \n( \n&#x5B;Entry_Datetime] ASC \n \n) on &#x5B;PRIMARY] \nGO \n\n<\/pre><\/div>\n\n\n<p>The tables have the same data in it. The difference between the tables is, that one is a heap, one has clustered index and one has a clustered Index which will be partitioned in the next step:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"437\" height=\"338\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-45.png\" alt=\"Image: Generated data\" class=\"wp-image-31319\" style=\"width:485px;height:auto\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-45.png 437w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-45-300x232.png 300w\" sizes=\"auto, (max-width: 437px) 100vw, 437px\" \/><\/figure>\n\n\n\n<p>After the tables are created with the corresponding data and indexes, the partition function and scheme must be created. This was done by the following script:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\n-- Create Partition Function as range right for every Year -10 Years \nCreate Partition Function &#x5B;myPF01_datetime] (datetime) \nAS Range Right for Values ( \nDATEADD(yy, DATEDIFF(yy, 0, GETDATE()) + 0, 0), DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) - 1, 0), DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) - 2, 0), \nDATEADD(yy, DATEDIFF(yy, 0, GETDATE()) - 3, 0), DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) - 4, 0), DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) - 5, 0),  \nDATEADD(yy, DATEDIFF(yy, 0, GETDATE()) - 6, 0), DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) - 7, 0), DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) - 8, 0),  \nDATEADD(yy, DATEDIFF(yy, 0, GETDATE()) - 9, 0), DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) - 10, 0) \n); \nGO \n \n-- Create Partition Scheme for Partition Function myPF01_datetime \nCREATE PARTITION SCHEME &#x5B;myPS01_datetime] \nAS PARTITION myPF01_datetime ALL TO (&#x5B;PRIMARY]) \nGO \n\n<\/pre><\/div>\n\n\n<p>I have used the DATEADD() function in combination with the DATEDIFF() function to retrieve the first millisecond of the year as datetime data type and that for the last 10 years and used this as range right boundary values. For sure it is also possible to hard code the boundary values like \u20182014-01-01 00:00:00.000\u2019 but I prefer to keep it as dynamically as possible. At the end it is the same result:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"463\" height=\"173\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-46.png\" alt=\"Image: Select Dateadd - function\" class=\"wp-image-31321\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-46.png 463w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-46-300x112.png 300w\" sizes=\"auto, (max-width: 463px) 100vw, 463px\" \/><\/figure>\n\n\n\n<p>After creating the partition function, I have created the partition scheme. The partition scheme is mapped to the partition function. In my case I assign every partition to the primary filegroup. It is also possible to split the partitions across multiple filegroups.<\/p>\n\n\n\n<p>As far as the partition function and scheme are created successfully it can be applied to the existing table: Table01_PARTITIONED. For achieving that, the clustered index of the table must be recreated on the partition scheme instead of the primary filegroup:\u00a0<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\n-- Apply partitiononing on Table: Table01_PARTITIONED through recreating the Tables Clustered Index ClusteredIndex_Table01_PARTITIONED on Partition Scheme myPS01_datetime \nCREATE CLUSTERED INDEX &#x5B;ClusteredIndex_Table01_PARTITIONED] ON &#x5B;dbo].&#x5B;Table01_PARTITIONED] \n( \n&#x5B;Entry_Datetime] ASC \n \n) with (DROP_EXISTING = ON) on myPS01_datetime(Entry_Datetime);  \nGO \n\n<\/pre><\/div>\n\n\n<p>After doing that, the Table Table01_PARTITIONED has multiple partitions while the other tables have still only one partition:\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"560\" height=\"235\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-47.png\" alt=\"Image: Partitions of partitioned table\" class=\"wp-image-31322\" style=\"width:763px;height:auto\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-47.png 560w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-47-300x126.png 300w\" sizes=\"auto, (max-width: 560px) 100vw, 560px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"589\" height=\"165\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-48.png\" alt=\"Image: Partitions of clustered index table\" class=\"wp-image-31323\" style=\"width:766px;height:auto\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-48.png 589w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-48-300x84.png 300w\" sizes=\"auto, (max-width: 589px) 100vw, 589px\" \/><\/figure>\n\n\n\n<p>There are at all 12 partitions for every year between 2014 and 2024 as well as one for every entry which has an earlier datetime than 2014-01-01 00:00:00.000 and one for every entry that has a later datetime value than 2024-01-01 00:00:00.000 while partition nr. 1 has the earliest data and partition nr. 12 has the latest data in it. See below:\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"602\" height=\"178\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-49.png\" alt=\"Image: Content of partition 1\" class=\"wp-image-31324\" style=\"width:825px;height:auto\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-49.png 602w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-49-300x89.png 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"602\" height=\"161\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-50.png\" alt=\"Image: content of partition 12\" class=\"wp-image-31325\" style=\"width:830px;height:auto\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-50.png 602w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-50-300x80.png 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-demo-tests\">DEMO Tests:<\/h2>\n\n\n\n<p>First, I want to compare the performance when moving outdated data, which is older than 2014-01-01 00:00:00.000, from the table itself to a history table. For that purpose, I created a history table with the same data structure as the table Table01_CLUSTEREDINDEX:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: sql; title: ; notranslate\" title=\"\">\nUse &#x5B;TestPartition] \nGO \n \n--Create History Table \nCREATE TABLE &#x5B;dbo].&#x5B;Table01_HISTORY01]( \n&#x5B;Entry_Datetime] &#x5B;datetime] NOT NULL, \n&#x5B;Entry_Text] &#x5B;nvarchar](50) NULL \n) \nGO \n \n--Create Clustered Indexes for dbo.Table01_HISTORY01 \nCREATE CLUSTERED INDEX &#x5B;ClusteredIndex_Table01_HISTORY01] ON &#x5B;dbo].&#x5B;Table01_HISTORY01] \n( \n&#x5B;Entry_Datetime] ASC \n \n) on &#x5B;PRIMARY] \nGO \n\n<\/pre><\/div>\n\n\n<p>I am starting first with the table with the clustered index with a classic \u201cinsert into select\u201d statement:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"479\" height=\"271\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-51.png\" alt=\"Image: Select insert data into history\" class=\"wp-image-31326\" style=\"width:756px;height:auto\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-51.png 479w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-51-300x170.png 300w\" sizes=\"auto, (max-width: 479px) 100vw, 479px\" \/><\/figure>\n\n\n\n<p>We can see that we have 10932 reads in total and a total query run time of 761 milliseconds.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"486\" height=\"233\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-71.png\" alt=\"Image: Execution plan select insert\" class=\"wp-image-31374\" style=\"width:792px;height:auto\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-71.png 486w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-71-300x144.png 300w\" sizes=\"auto, (max-width: 486px) 100vw, 486px\" \/><\/figure>\n\n\n\n<p>In the execution plan, we can see that a classical Index seek operation occurred. Which means, the database engine seeked for every row which has a datetime value previous to 2014-01-01 00:00:00.000 and wrote it into the history table.<\/p>\n\n\n\n<p>For the delete operation we can see similar results:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"602\" height=\"215\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-70.png\" alt=\"Image: delete rows\" class=\"wp-image-31373\" style=\"width:717px;height:auto\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-70.png 602w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-70-300x107.png 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"429\" height=\"210\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-68.png\" alt=\"Image: Delete rows\" class=\"wp-image-31371\" style=\"width:710px;height:auto\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-68.png 429w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-68-300x147.png 300w\" sizes=\"auto, (max-width: 429px) 100vw, 429px\" \/><\/figure>\n\n\n\n<p>Totally 785099 rows where moved and we have in the table Table01_CLUSTEREDINDEX no older entries than 2014-01-01 00:00:00.000 anymore:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"513\" height=\"235\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-55.png\" alt=\"Image: Verify table content\" class=\"wp-image-31330\" style=\"width:601px;height:auto\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-55.png 513w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-55-300x137.png 300w\" sizes=\"auto, (max-width: 513px) 100vw, 513px\" \/><\/figure>\n\n\n\n<p>Next let us compare the data movement when using a \u201cswitch partition\u201d statement. For switching a partition from a partitioned source table to a nonpartitioned destination table, we need to use the partition number of the source table. For that I run the following query:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"493\" height=\"341\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-56.png\" alt=\"Image: Switch partition\" class=\"wp-image-31331\" style=\"width:689px;height:auto\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-56.png 493w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-56-300x208.png 300w\" sizes=\"auto, (max-width: 493px) 100vw, 493px\" \/><\/figure>\n\n\n\n<p>We can see that the partition number 1 was moved within <strong>2 milliseconds<\/strong>. Compared to the previous query where it took 761 milliseconds for inserting the data and an additional 596 milliseconds for deleting the data, the switch partition operation is obviously much faster. But why is this the case? \u2013 that\u2019s because switching partitions is a metadata operation. It does not seeking through an index (or even worse \u2013 scanning a table) and write every row one by one, instead it changes the metadata of the partition and remaps the partition to the target table.\u00a0<\/p>\n\n\n\n<p>And as we can see, we have the same result:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"534\" height=\"264\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-57.png\" alt=\"Image: verify table content\" class=\"wp-image-31332\" style=\"width:604px;height:auto\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-57.png 534w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-57-300x148.png 300w\" sizes=\"auto, (max-width: 534px) 100vw, 534px\" \/><\/figure>\n\n\n\n<p>Another big advantage is when it comes to deleting a whole data range. For example: Let us delete the entries of the year 2017 \u2013 we do not need them anymore.<\/p>\n\n\n\n<p>For the table with the clustered Index, we must use a statement like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"438\" height=\"246\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-67.png\" alt=\"Image: delete operation\" class=\"wp-image-31369\" style=\"width:794px;height:auto\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-67.png 438w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-67-300x168.png 300w\" sizes=\"auto, (max-width: 438px) 100vw, 438px\" \/><\/figure>\n\n\n\n<p>We can see that we have here a query runtime of 355 milliseconds and 68351 page reads in total for the delete operation with the clustered index.\u00a0<\/p>\n\n\n\n<p>For the partitioned table instead, we can use a truncate operation on the specific partition. That\u2019s because the partition is treated as a own physical unit and can for that be truncated.<\/p>\n\n\n\n<p>And as we should know: Truncating is much faster, because this operation is deallocating the pages and writes only one transaction log entry for the page deallocation while a delete operation is going row by row and writes every row deletion in the transaction log.<\/p>\n\n\n\n<p>So, let us try: The year 2017 is 7 years back so let us verify, that the right data range will be deleted:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"549\" height=\"277\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-66.png\" alt=\"Image: verify partition content\" class=\"wp-image-31368\" style=\"width:751px;height:auto\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-66.png 549w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-66-300x151.png 300w\" sizes=\"auto, (max-width: 549px) 100vw, 549px\" \/><\/figure>\n\n\n\n<p>We can see with the short query above: 7 Years back, that would be the partition nr. 5 and the data range seems to be right.\u00a0 So, let us truncate:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"602\" height=\"399\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-60.png\" alt=\"Image: Truncate partition\" class=\"wp-image-31335\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-60.png 602w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-60-300x199.png 300w\" sizes=\"auto, (max-width: 602px) 100vw, 602px\" \/><\/figure>\n\n\n\n<p>And we can see to truncate all the entries from the year 2017, the database engine took 1 millisecond compared to the 355 seconds for the delete operation again much faster.<\/p>\n\n\n\n<p>Next: let\u2019s see, how we can change the lock behavior of SQL-Server through partitioning.\u00a0For that I ran the following update query for updating every entry text for dates which are younger than May 2018:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"540\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/1-1024x540.png\" alt=\"Image: Update data entries\" class=\"wp-image-31359\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/1-1024x540.png 1024w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/1-300x158.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/1-768x405.png 768w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/1.png 1059w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>While the update operation above was running, I queried the DMV sys.dm_tran_locks in another session for checking the locks my update operation above is holding:\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"761\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/2-1024x761.png\" alt=\"Image: lock contention\" class=\"wp-image-31360\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/2-1024x761.png 1024w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/2-300x223.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/2-768x571.png 768w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/2.png 1051w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>And we can see that we have a lot of page locks and also an exclusive lock on the object itself (in this case the Table01_HEAP).\u00a0\u00a0That is because of SQL-Servers lock escalation behavior.<\/p>\n\n\n\n<p>I ran the same update operation on the partitioned table but before I changed the lock escalation setting of the table from default value \u201ctable\u201d to \u201cauto\u201d. This is necessary for enable locking on partition level:\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"933\" height=\"519\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/3.png\" alt=\"Image: Update lock escalation\" class=\"wp-image-31361\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/3.png 933w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/3-300x167.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/3-768x427.png 768w\" sizes=\"auto, (max-width: 933px) 100vw, 933px\" \/><\/figure>\n\n\n\n<p>And when I\u2019m querying the dmv again while the update operation above is running, I get the following result:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"756\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/4-1024x756.png\" alt=\"Image: lock contention\" class=\"wp-image-31363\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/4-1024x756.png 1024w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/4-300x222.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/4-768x567.png 768w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/4.png 1052w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>We can see that we have no exclusive look on abject level anymore, we have an intended exclusive look, which will not prevent other transactions from accessing the data (as far as it has no other look on a more granular level). Instead, we have multiple exclusive looks on multiple resources called HOBT. And when we take a look at the \u201cresource_associated_entity_id\u201d and using them for querying the sys.partitions table, we can see the following information&#8217;s:\u00a0<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"925\" height=\"627\" src=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/5-3.png\" alt=\"Image: locked partitions\" class=\"wp-image-31366\" srcset=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/5-3.png 925w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/5-3-300x203.png 300w, https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/5-3-768x521.png 768w\" sizes=\"auto, (max-width: 925px) 100vw, 925px\" \/><\/figure>\n\n\n\n<p>These resources locked through the update operation on the partitioned table are the partitions associated with the table. So, SQL-Server locked the partitions instead of locking the whole table. This has the advantage that locking happens in a more granular context which prevents lock contention on the table itself.\u00a0<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-conclusion\"><strong>Conclusion:<\/strong><\/h2>\n\n\n\n<p>Partitioning can be a very powerful and useful functionality in SQL-Server when used in an appropriate situation. Especially when it comes to regular operations on whole data ranges, partitioning can be used for enhancing performance and manageability. With partitioning, it\u2019s also possible to distribute the data of a table over multiple files groups. Additionally with splitting and merging partitions it\u2019s possible to maintain partitions for growing or shrinking data.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction:\u00a0 When it comes to moving ranges of data with many rows across different tables in SQL-Server, the partitioning functionality of SQL-Server can provide a good solution for manageability and performance optimizing. In this blog we will look at the different advantages and the concept of partitioning in SQL-Server. Concept overview:\u00a0 In SQL-Server, partitioning can [&hellip;]<\/p>\n","protected":false},"author":145,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[198,368,99],"tags":[51],"type_dbi":[],"class_list":["post-31316","post","type-post","status-publish","format-standard","hentry","category-database-management","category-development-performance","category-sql-server","tag-sql-server"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.2 (Yoast SEO v27.4) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>SQL Server: Manage large data ranges using partitioning - dbi Blog<\/title>\n<meta name=\"description\" content=\"Blog about how to use SQL-Server partitioning for manage large data ranges and enhancing performance and manageability.\" \/>\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\/sql-server-manage-large-data-ranges-using-partitioning\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"SQL Server: Manage large data ranges using partitioning\" \/>\n<meta property=\"og:description\" content=\"Blog about how to use SQL-Server partitioning for manage large data ranges and enhancing performance and manageability.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/\" \/>\n<meta property=\"og:site_name\" content=\"dbi Blog\" \/>\n<meta property=\"article:published_time\" content=\"2024-02-26T16:59:52+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-02-26T16:59:55+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-43.png\" \/>\n<meta name=\"author\" content=\"Hocine Mechara\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Hocine Mechara\" \/>\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\\\/sql-server-manage-large-data-ranges-using-partitioning\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-manage-large-data-ranges-using-partitioning\\\/\"},\"author\":{\"name\":\"Hocine Mechara\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/29415d02bc1b50884796a01cf649951f\"},\"headline\":\"SQL Server: Manage large data ranges using partitioning\",\"datePublished\":\"2024-02-26T16:59:52+00:00\",\"dateModified\":\"2024-02-26T16:59:55+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-manage-large-data-ranges-using-partitioning\\\/\"},\"wordCount\":1580,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-manage-large-data-ranges-using-partitioning\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2024\\\/02\\\/image-43.png\",\"keywords\":[\"SQL Server\"],\"articleSection\":[\"Database management\",\"Development &amp; Performance\",\"SQL Server\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-manage-large-data-ranges-using-partitioning\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-manage-large-data-ranges-using-partitioning\\\/\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-manage-large-data-ranges-using-partitioning\\\/\",\"name\":\"SQL Server: Manage large data ranges using partitioning - dbi Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-manage-large-data-ranges-using-partitioning\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-manage-large-data-ranges-using-partitioning\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2024\\\/02\\\/image-43.png\",\"datePublished\":\"2024-02-26T16:59:52+00:00\",\"dateModified\":\"2024-02-26T16:59:55+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/#\\\/schema\\\/person\\\/29415d02bc1b50884796a01cf649951f\"},\"description\":\"Blog about how to use SQL-Server partitioning for manage large data ranges and enhancing performance and manageability.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-manage-large-data-ranges-using-partitioning\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-manage-large-data-ranges-using-partitioning\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-manage-large-data-ranges-using-partitioning\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2024\\\/02\\\/image-43.png\",\"contentUrl\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/2\\\/2024\\\/02\\\/image-43.png\",\"width\":331,\"height\":66},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/sql-server-manage-large-data-ranges-using-partitioning\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"SQL Server: Manage large data ranges using partitioning\"}]},{\"@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\\\/29415d02bc1b50884796a01cf649951f\",\"name\":\"Hocine Mechara\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f771f838feed0619485da1e42ae05d771dcb446e1f4785244582280315fa73c3?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f771f838feed0619485da1e42ae05d771dcb446e1f4785244582280315fa73c3?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f771f838feed0619485da1e42ae05d771dcb446e1f4785244582280315fa73c3?s=96&d=mm&r=g\",\"caption\":\"Hocine Mechara\"},\"url\":\"https:\\\/\\\/www.dbi-services.com\\\/blog\\\/author\\\/hocinemechara\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"SQL Server: Manage large data ranges using partitioning - dbi Blog","description":"Blog about how to use SQL-Server partitioning for manage large data ranges and enhancing performance and manageability.","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\/sql-server-manage-large-data-ranges-using-partitioning\/","og_locale":"en_US","og_type":"article","og_title":"SQL Server: Manage large data ranges using partitioning","og_description":"Blog about how to use SQL-Server partitioning for manage large data ranges and enhancing performance and manageability.","og_url":"https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/","og_site_name":"dbi Blog","article_published_time":"2024-02-26T16:59:52+00:00","article_modified_time":"2024-02-26T16:59:55+00:00","og_image":[{"url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-43.png","type":"","width":"","height":""}],"author":"Hocine Mechara","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Hocine Mechara","Est. reading time":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/#article","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/"},"author":{"name":"Hocine Mechara","@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/29415d02bc1b50884796a01cf649951f"},"headline":"SQL Server: Manage large data ranges using partitioning","datePublished":"2024-02-26T16:59:52+00:00","dateModified":"2024-02-26T16:59:55+00:00","mainEntityOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/"},"wordCount":1580,"commentCount":0,"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-43.png","keywords":["SQL Server"],"articleSection":["Database management","Development &amp; Performance","SQL Server"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/","url":"https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/","name":"SQL Server: Manage large data ranges using partitioning - dbi Blog","isPartOf":{"@id":"https:\/\/www.dbi-services.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/#primaryimage"},"image":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/#primaryimage"},"thumbnailUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-43.png","datePublished":"2024-02-26T16:59:52+00:00","dateModified":"2024-02-26T16:59:55+00:00","author":{"@id":"https:\/\/www.dbi-services.com\/blog\/#\/schema\/person\/29415d02bc1b50884796a01cf649951f"},"description":"Blog about how to use SQL-Server partitioning for manage large data ranges and enhancing performance and manageability.","breadcrumb":{"@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/#primaryimage","url":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-43.png","contentUrl":"https:\/\/www.dbi-services.com\/blog\/wp-content\/uploads\/sites\/2\/2024\/02\/image-43.png","width":331,"height":66},{"@type":"BreadcrumbList","@id":"https:\/\/www.dbi-services.com\/blog\/sql-server-manage-large-data-ranges-using-partitioning\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/www.dbi-services.com\/blog\/"},{"@type":"ListItem","position":2,"name":"SQL Server: Manage large data ranges using partitioning"}]},{"@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\/29415d02bc1b50884796a01cf649951f","name":"Hocine Mechara","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f771f838feed0619485da1e42ae05d771dcb446e1f4785244582280315fa73c3?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f771f838feed0619485da1e42ae05d771dcb446e1f4785244582280315fa73c3?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f771f838feed0619485da1e42ae05d771dcb446e1f4785244582280315fa73c3?s=96&d=mm&r=g","caption":"Hocine Mechara"},"url":"https:\/\/www.dbi-services.com\/blog\/author\/hocinemechara\/"}]}},"_links":{"self":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/31316","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\/145"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/comments?post=31316"}],"version-history":[{"count":25,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/31316\/revisions"}],"predecessor-version":[{"id":31378,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/posts\/31316\/revisions\/31378"}],"wp:attachment":[{"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/media?parent=31316"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/categories?post=31316"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/tags?post=31316"},{"taxonomy":"type","embeddable":true,"href":"https:\/\/www.dbi-services.com\/blog\/wp-json\/wp\/v2\/type_dbi?post=31316"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}