Download What is Table Partitioning? - SQL Server Consultation

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts

Open Database Connectivity wikipedia , lookup

SQL wikipedia , lookup

Functional Database Model wikipedia , lookup

Clusterpoint wikipedia , lookup

Microsoft SQL Server wikipedia , lookup

Entity–attribute–value model wikipedia , lookup

PL/SQL wikipedia , lookup

Object-relational impedance mismatch wikipedia , lookup

Relational model wikipedia , lookup

Join (SQL) wikipedia , lookup

Extensible Storage Engine wikipedia , lookup

Database model wikipedia , lookup

Transcript
SQL Server Technical Article
Table Partitioning Implementation with advanced scenarios
Writer: Mustafa EL-Masry
Technical Reviewer: SQLSERVER Performance tuning (http://sqlserver-performance-tuning.net/)
Published: December 2014
Applies to: SQL Server 2012, 2014
SlideShare: http://www.slideshare.net/MostafaElmasry3/table-partitioning-implementation-with-
advanced-scenarios-43436743
About The Writer
I am Mustafa El-Masry Senior Database administrator and DB Analyst of the Ministry of Higher Education
(The first DB environment over KSA as accredited by Microsoft ), also I have deep practical knowledge about
T-SQL performance , HW Performance issues, Data Warehousing and data mart solutions , SQL Server
Replication, Clustering solutions (Active Active and active passive)and Database Designs for different kinds of
systems , HAG, diving deeply more :
Founder of Community :SQL DATABASE ADMINISTRATION
https://mostafaelmasry.wordpress.com/
Audience Marketing Manager and Executive Board member : SQLSERVER PERFORMANCE TUNING
COMMUNITY http://sqlserver-performance-tuning.net/
in fluent Participator at Microsoft Forums of SQL Server at http://Social.technet.microsoft.com
Microsoft Profile :https://www.mcpvirtualbusinesscard.com/VBCServer/EngMostafaElamsry/profile
Chart for all my posts: http://sqlserver-performance-tuning.net/?p=4526
If you have any issue any Performance Case , disaster recovery anything related to SQL Server technology.
Please do not hesitate to contact me to arrange a time. I am available by phone at +966 543990968,
00201114668821 or VIA mail [email protected] , [email protected]
Linked in: https://www.linkedin.com/in/mostafaelmasry
SQL Training: https://mostafaelmasry.wordpress.com/training/
Summary: Table partitioning can make very large tables and indexes easier to manage, and
improve the performance of appropriately filtered queries. This paper contains a thorough
coverage of strategies for partitioning tables, including the required partition functions and
partition schemes. The benefits of partition elimination, partition parallelism, and index partition
maintenance are also explored. These strategies are applied to various partitioning scenarios
such as the sliding window scenario, data archiving, and partition consolidation and movement.
Introduction and overview
When a database table grows in size to the hundreds of gigabytes or more, it can become more
difficult to load new data, remove old data, and maintain indexes. Just the sheer size of the
table causes such operations to take much longer. Even the data that must be loaded or
removed can be very sizable, making INSERT and DELETE operations on the table impractical.
The Microsoft® SQL Server® 2012 database software provides table partitioning to make such
operations more manageable.
Partitioning a large table divides the table and its indexes into smaller partitions, so that
maintenance operations can be applied on a partition-by-partition basis, rather than on the
entire table. In addition, the SQL Server optimizer can direct properly filtered queries to
appropriate partitions rather than the entire table.
This paper covers strategies and best practices for using partitioned tables and indexes in SQL
Server 2012. It is intended for database architects, developers, and administrators of both data
warehouse and OLTP systems, and the material is presented at an intermediate to advanced
level. For more Information:
Table Partitioning Implementation with advanced scenarios (Part 1)
http://sqlserver-performance-tuning.net/?p=5061
Table Partitioning Implementation with advanced scenarios (Part 2)
http://sqlserver-performance-tuning.net/?p=5075
Table Partitioning Implementation with advanced scenarios (Part 3)
http://sqlserver-performance-tuning.net/?p=5091
Table Partitioning Implementation with advanced scenarios (Part 4)
http://sqlserver-performance-tuning.net/?p=5098
What is Table Partitioning?
Table partitioning consists in a technique adopted by some
database management systems to deal with large databases.
Instead of a single table storage location, they split your table
in several files for quicker queries. If you have a table which
will store large amounts of data (I mean REALLY large
amounts, like millions of records) table partitioning will be a
good option. Queries that access only a fraction of the data can run faster because there is less data to scan.
Why we need to use Table Partitioning?
Where tables and indexes become very large, partitioning can help by splitting large amounts of data into
smaller more manageable chunks, the type of partitioning described in this post is termed horizontal
partitioning. With horizontal partitioning, large chunks of rows will be stored in multiple separate partitions.
The definition of the partitioned set is customized, defined, and managed – by your needs. Partitioning in SQL
Server 2005 allows you to partition your tables based on specific data usage patterns using defined ranges.
Pros and Cons of Partitioning in SQL Server?
PROS:

Low overhead (locks, speed) in sliding large amounts of data into separate table for truncation (our
primary concern)

Increased performance.

No need to create separate physical tables for each ranges manually.

There are few limitations when you insert data into Partition View like you cannot use BULK
INSERT/BCP etc.

Less complex to manage and administrate

SQL Server automatically manages the placement of data in the proper partitions.
CONS
Major disadvantage is, we cannot have different index model
for different range…In general, and we may need to have
more number of indexes when the data is READ ONLY and less or different index model for the data which is
READWRITE. That is not possible with partition table.

You cannot rebuild a partitioned index with the ONLINE option set to ON, because the entire table will be
locked during the rebuild.

Additional data required in indexes (and queries) to have aligned indexes

Other limitations associated with aligned indexes?
Table patriating rules

You cannot change the data type of the partitioning column
once the table is partitioned.

You can move an index to a partition scheme after it has been
created.

You cannot use the SWITCH option of ALTER TABLE statement
on replicated tables.

For a unique key or primary key index to be partitioned, the
partitioning key must be part of the unique key (or the index key).

Partitioning key of an index doesn’t have to be part of the index key. For More information check this Link
http://www.toadworld.com/platforms/sql-server/w/wiki/9655.partitioned-table-rules-and-gotchas.aspx
What is the Difference Partitioning Type on SQL SERVER
We have two kind of partitioning in SQL Server Vertical Partitioning and Horizontal Partitioning let’s go
deeply to know what is the difference between the two types
For more Information about Horizontal Partitioning, Vertical Partitioning and Hardware Partitioning go for
this Link
http://technet.microsoft.com/en-us/library/ms178148(v=sql.105).aspx
Vertical Partitioning
Vertical partitioning segments columns into multiple tables containing the same rows Vertical partitioning
divides a table into multiple tables that contain fewer columns. Vertical Partitioning The two types of vertical
partitioning are normalization and row splitting: by removing some columns from the primary table to
Secondary table that are linked to the primary table by primary key and foreign key relationships. We cannot
decide vertical partitioning is good or bad from the performance
because it’s based on x of reasons (Column Data Type, Column Size,
and Volume of data …) so it’s ultimately not good not bad. As we can
see from the image based on our requirement and our Queries
hitting this table we can diced how we can splitting the Table by this
way we will reduce the IO and CPU for the query scan
When I can use Vertical Partitioning:
If I had 100 columns (or some large number) and didn’t often query some of them, or queried others very
often, then I can save I/O and unneeded reads by moving some data to another table. Like the Example on the
image
Horizontal Partitioning
Horizontal partitioning divides a table into multiple tables. Each table have
the same columns (Same table structure but the data distributed in this
multiple tables according the igure2 Rang partition so if we have Millions
of record we can partitioned horizontally into Multiple tables so any Query
hitting our data will select from the Specific table and by this we will fast
the Query Execution and the IO.
Table partitioning dependence
Partitioning Function
That maps the rows of a table or index into partitions based on the boundary_value , we can build the
Partition Function by two ways based on our
Requirement and our business needed


RANGE RIGHT
RANGE LEFT
Another thing the boundary value we can do it on three
data type



INT COLUMN
DATETIME COLUMN
CHAR COLUMN
Partitioning Scheme
That maps the partitions of a partitioned table or index to filegroups, partition scheme must be created on
partition function, partition scheme can be used for one or more partitioned tables, indexes, and indexed
views.
Partitioning Table/Index
is tied to a particular partition scheme when it is created, partition table has only an indirect relationship,
through the partition scheme, to the partition function at the end The relationship between a partition
function and a partition scheme is one-to-many as is the relationship between a partition scheme and
partitioned tables and indexes, because moving data in and out of a partitioned table usually requires
modifying the partition function for more information:

Partitioned Tables and Indexes in SQL Server 2005 at http://msdn.microsoft.com/enus/library/ms345146.aspx

Strategies for Partitioning Relational Data Warehouses in Microsoft SQL Server at
http://technet.microsoft.com/en-us/library/cc966457.aspx
let’s go now for the TECHNICAL DEMO to know How we can implement the table partitioning step by
step from Scratch

Range Direction

How to implement Table partitioning Step by step (RANGE LEFT)

How to implement table partitioning step by step (RANGE RIGHT)
Implement Partitioned Table with Range Right
to implement any partitioned table from SCRATCH we have basic 6 steps we will do it now by T-SQL and by
SQL SERVER WIZARD






Create Database (T-SQL / Wizard)
Create FILEGROUP (T-SQL / Wizard)
Create files and add it to the FILEGROUP (T-SQL / Wizard)
Create partition Function (RANGE RIGHT / RANGE LEFT) (T-SQL only)
Create partition Scheme (T-SQL only)
Create Table Partitioning (T-SQL only)
At the first i will do it by T-SQL
Create Database
I will create new database [DBForPartitioning] to be for our entire workshop to the end of the series
CREATE DATABASE [DBForPartitioning]
GO
ALTER DATABASE [DBForPartitioning]
MODIFY FILE ( NAME = N'DBForPartitioning', SIZE = 256MB , MAXSIZE = 10GB , FILEGROWTH =
512MB );
ALTER DATABASE [DBForPartitioning]
MODIFY FILE ( NAME = N'DBForPartitioning_log', SIZE = 128MB , FILEGROWTH = 128MB );
GO
Create Filegroups
Here we will create four filegroup (FG1, FG2, FG3, and FG4) to can use it on the Partition Scheme
USE [master]
GO
ALTER DATABASE [DBForPartitioning] ADD FILEGROUP [FG1]
ALTER DATABASE [DBForPartitioning] ADD FILEGROUP [FG2]
ALTER DATABASE [DBForPartitioning] ADD FILEGROUP [FG3]
ALTER DATABASE [DBForPartitioning] ADD FILEGROUP [FG4]
GO
Create Files and add it to Filegroups
In this step I will create four files and add it on the FILEGROUP and all of this i will do it dynamically
Use DBForPartitioning
Go
DECLARE @path NVARCHAR(256) ,
@i TINYINT= 1 ,
@sql NVARCHAR(4000);
SELECT TOP 1
@path = LEFT(physical_name, LEN(physical_name) - 4)
FROM sys.database_files
WHERE name = 'DBForPartitioning'
WHILE @i <= 4
BEGIN
SET @sql = N'ALTER DATABASE DBForPartitioning ADD FILE (name=File' + CAST(@i AS
NCHAR(1)) + ',
filename=''' + @path + N'File' + CAST(@i AS NCHAR(1)) + '.ndf' + ''',
size=128MB, filegrowth=256MB) TO FILEGROUP FG' + CAST(@i AS NCHAR(1))
RAISERROR (@sql,0,0)
EXEC sp_executesql @sql;
SET @i += 1;
END
GO
Range Direction Right and Date time Boundary Values
Next three steps I will do everything on the RANGE RIGHT and RANGE LEFT so I will work on parallel
Create Partitioning Function
In this case I will do partition function with boundary_value DATETIME and
Use DBForPartitioning
GO
CREATE PARTITION FUNCTION PF_DBForPartitioning_RangeRight (datetime)
AS RANGE RIGHT FOR VALUES ( '2008-01-01','2009-01-01', '2010-01-01');
Create Partitioning Scheme
I will create Partition scheme on PF (PF_DBForPartitioning_RangeRight) on the four filegroup
Use DBForPartitioning
GO
CREATE PARTITION SCHEME PS_DBForPartitioning_RangeRight
AS PARTITION PF_DBForPartitioning_RangeRight
TO (FG1, FG2, FG3 ,FG4)
GO
Create Table Partitioning
Now i will create table partitioning on Partitioning Scheme [PS_DBForPartitioning_RangeRight] on datetime
Column
Use DBFOrPartitioning
GO
CREATE TABLE Partitioning_RangeRight
(Partitioning_ID int ,
Partitioning_time datetime)
ON PS_DBForPartitioning_RangeRight (Partitioning_time);
GO
Now the sex basic steps for any table partitioning is finished and I will go now for fill the table by some test
data then I will show some wonderful Stored Procedures and Scripts it will return to us all the information
about the Partition Function ,Partition Scheme and table Partition , ….etc.
Fill Table by adequate volumes of data
Use DBFOrPartitioning
GO
INSERT INTO Partitioning_RangeRight (Partitioning_ID, Partitioning_time)
SELECT 1 ,'2007-01-01'UNION ALL
SELECT 2 ,'2007-10-01'UNION ALL
SELECT 3 ,'2008-01-01'UNION ALL
SELECT 4 ,'2008-08-09'UNION ALL
SELECT 5 ,'2008-12-30'UNION ALL
SELECT 6 ,'2009-01-01'UNION ALL
SELECT 7 ,'2009-05-24'UNION ALL
SELECT 8 ,'2010-01-24'UNION ALL
SELECT 9 ,'2010-05-24'UNION ALL
SELECT 10,'2011-05-24'
GO
How to Monitor Partitioned Table (Part1)
Select Partitioned Table in DB
Use DBFOrPartitioning
GO
select distinct t.name
from sys.partitions p
inner join sys.tables t
on p.object_id = t.object_id
where p.partition_number <> 1
Stored Procedure to return Partitioned Columns
Create Proc partitioning_Column (@Table_Name Nvarchar(500))
AS
Begin
SELECT CAST(ic.partition_ordinal AS INT) AS [ID],
c.name AS ColumnName
FROM sys.tables AS tbl
INNER JOIN sys.indexes AS idx
ON idx.object_id = tbl.object_id
AND idx.index_id < 2
INNER JOIN sys.index_columns ic
ON (ic.partition_ordinal > 0)
AND (ic.index_id = idx.index_id
AND ic.object_id = CAST(tbl.object_id AS INT))
INNER JOIN sys.columns c
ON c.object_id = ic.object_id
AND c.column_id = ic.column_id
WHERE (tbl.name = @Table_Name
AND SCHEMA_NAME(tbl.schema_id) = 'dbo')
ORDER BY [ID]
END
Exec partitioning_Column 'Partitioning_RangeRight'
Select Partition_Id with partition_Number
select partition_id, index_id, partition_number, Rows
FROM sys.partitions
WHERE OBJECT_NAME(OBJECT_ID)='Partitioning_RangeRight'
GO
Select Partition Function and partition Scheme name
select ps.Name PartitionScheme, pf.name PartitionFunction
from sys.indexes i
join sys.partition_schemes ps on ps.data_space_id = i.data_space_id
join sys.partition_functions pf on pf.function_id = ps.function_id
where i.object_id = object_id('Partitioning_RangeRight')
Stored procedure To return all Detail about the data
Create proc PartitionTableDetail(@tablename Nvarchar(500))
As
begin
SELECT
ISNULL(quotename(ix.name),'Heap') as IndexName
,ix.type_desc as type
,prt.partition_number
,prt.data_compression_desc
,ps.name as PartitionScheme
,pf.name as PartitionFunction
,fg.name as FilegroupName
,case when ix.index_id < 2 then prt.rows else 0 END as Rows
,au.TotalMB
,au.UsedMB
,case when pf.boundary_value_on_right = 1 then 'less than' when
pf.boundary_value_on_right is null then '' else 'less than or equal to' End as Comparison
,fg.name as FileGroup
,rv.value As Rang_value,
T.name AS Range_Type
FROM sys.partitions prt
inner join sys.indexes ix
on ix.object_id = prt.object_id and
ix.index_id = prt.index_id
inner join sys.data_spaces ds
on ds.data_space_id = ix.data_space_id
left join sys.partition_schemes ps
on ps.data_space_id = ix.data_space_id
left join sys.partition_functions pf
on pf.function_id = ps.function_id
inner join sys.partition_parameters PP
on pf.function_id = PP.function_id
inner join sys.types t
on t.system_type_id = PP.system_type_id
left join sys.partition_range_values rv
on rv.function_id = pf.function_id AND
rv.boundary_id = prt.partition_number
left join sys.destination_data_spaces dds
on dds.partition_scheme_id = ps.data_space_id AND
dds.destination_id = prt.partition_number
left join sys.filegroups fg
on fg.data_space_id = ISNULL(dds.data_space_id,ix.data_space_id)
inner join (select str(sum(total_pages)*8./1024,10,2) as [TotalMB]
,str(sum(used_pages)*8./1024,10,2) as [UsedMB]
,container_id
from sys.allocation_units
group by container_id) au
on au.container_id = prt.partition_id
WHERE prt.OBJECT_ID = object_id(@tablename)
order by ix.type_desc;
END
Exec PartitionTableDetail 'Partitioning_RangeRight'
Implement Partitioned Table with Range Left
Create Partitioning Function
In this case i will do partition function with boundary_value DATETIME and
GO
CREATE PARTITION FUNCTION PF_DBForPartitioning_RangeLeft (datetime)
AS RANGE left FOR VALUES ( '2008-01-01','2009-01-01', '2010-01-01');
Create Partitioning Scheme
I will create Partition scheme on PF(PF_DBForPartitioning_Rangeleft) on the four filegroup
Use DBForPartitioning
GO
CREATE PARTITION SCHEME PS_DBForPartitioning_Rangeleft
AS PARTITION PF_DBForPartitioning_RangeLeft
TO (FG1, FG2, FG3 ,FG4)
Create Table Partitioning
Now I will create table partitioning on Partitioning Scheme [PS_DBForPartitioning_RangeLeft] on datetime
Column
Use DBFOrPartitioning
GO
CREATE TABLE Partitioning_Rangeleft
(Partitioning_ID int ,
Partitioning_time datetime)
ON PS_DBForPartitioning_Rangeleft (Partitioning_time);
GO
Fill Table by adequate volumes of data
Use DBFOrPartitioning
GO
INSERT INTO Partitioning_Rangeleft (Partitioning_ID, Partitioning_time)
SELECT 1 ,'2007-01-01'UNION ALL
SELECT 2 ,'2007-10-01'UNION ALL
SELECT 3 ,'2008-01-01'UNION ALL
SELECT 4 ,'2008-08-09'UNION ALL
SELECT 5 ,'2008-12-30'UNION ALL
SELECT
SELECT
SELECT
SELECT
SELECT
GO
6 ,'2009-01-01'UNION
7 ,'2009-05-24'UNION
8 ,'2010-01-24'UNION
9 ,'2010-05-24'UNION
10,'2011-05-24'
ALL
ALL
ALL
ALL
Now to know more information about the data inserted and the table partition please check the and Execute
the Stored procedure [PartitionTableDetail]
Exec PartitionTableDetail 'Partitioning_Rangeleft'
also you can Execute the below query it will return to you all the information about the current partition
function and partition Schema Exist on DB [] and the boundary_value
SELECT f.NAME AS file_group_name,
SCHEMA_NAME(t.schema_id) AS table_schema,
t.name AS table_name,
p.partition_number,
ISNULL(CAST(left_prv.value AS VARCHAR(MAX))+ CASE WHEN pf.boundary_value_on_right = 0
THEN ' < '
ELSE ' <= '
END , '-INF < ')
+ 'X' + ISNULL(CASE WHEN pf.boundary_value_on_right = 0 THEN ' <= '
ELSE ' < '
END + CAST(right_prv.value AS NVARCHAR(MAX)), ' < INF') AS range_desc,
pf.boundary_value_on_right,
ps.name AS partition_schem_name,
pf.name AS partition_function_name,
left_prv.value AS left_boundary,
right_prv.value AS right_boundary
FROM sys.partitions p
JOIN sys.tables t
ON p.object_id = t.object_id
JOIN sys.indexes i
ON p.object_id = i.object_id
AND p.index_id = i.index_id
JOIN sys.allocation_units au
ON p.hobt_id = au.container_id
JOIN sys.filegroups f
ON au.data_space_id = f.data_space_id
LEFT JOIN sys.partition_schemes ps
ON ps.data_space_id = i.data_space_id
LEFT JOIN sys.partition_functions pf
ON ps.function_id = pf.function_id
LEFT JOIN sys.partition_range_values left_prv
ON left_prv.function_id = ps.function_id
AND left_prv.boundary_id + 1 = p.partition_number
LEFT JOIN sys.partition_range_values right_prv
ON right_prv.function_id = ps.function_id
AND right_prv.boundary_id = p.partition_number
How to Monitor Partitioned Table (Part2)
Determined the partition in which particular row is stored
Only you need to put your table name as example if i need to know the inserted row with
[Partitioning_time] = ‘2008-01-01 00:00:00.000′ inserted in witch Partition in the table
[Partitioning_Rangeleft]
with cte as(
SELECT T.*,
DDDPA.partition_id AS partition_number,
ISNULL
(
CAST(LEFT_PRV.value AS VARCHAR(MAX)) +
CASE WHEN PF.boundary_value_on_right = 0 THEN ' < ' ELSE ' <= ' END ,
'-INF < '
) +
'X' +
ISNULL
(
CASE WHEN PF.boundary_value_on_right = 0 THEN ' <= ' ELSE ' < ' END +
CAST(RIGHT_PRV.value AS NVARCHAR(MAX)),
' < INF'
) AS range_desc,
PF.boundary_value_on_right
FROM dbo.Partitioning_Rangeleft AS T
CROSS APPLY sys.fn_PhysLocCracker(T.%%physloc%%) AS FPLC
JOIN sys.dm_db_database_page_allocations(DB_ID(),NULL,NULL,NULL,NULL) AS DDDPA
ON DDDPA.allocated_page_page_id = FPLC.page_id
AND DDDPA.allocated_page_file_id = FPLC.file_id
JOIN sys.indexes AS I
ON DDDPA.object_id = I.object_id
AND DDDPA.index_id = I.index_id
LEFT JOIN sys.partition_schemes PS
ON PS.data_space_id = I.data_space_id
LEFT JOIN sys.partition_functions pf
ON ps.function_id = pf.function_id
LEFT JOIN sys.partition_range_values left_prv
ON left_prv.function_id = ps.function_id
AND left_prv.boundary_id + 1 = DDDPA.partition_id
LEFT JOIN sys.partition_range_values right_prv
ON right_prv.function_id = ps.function_id
AND right_prv.boundary_id = DDDPA.partition_id)
Select * from CTE
where Partitioning_time ='2008-01-01 00:00:00.000';
Or by another simple way but at this time you will select from the Partition function not from the table
SELECT $PARTITION.PF_DBForPartitioning_RangeLeft ('2008-01-01 00:00:00.000') ;
GO
Special Condition for partitions
Merge
IF you wanted to remove a boundary instead. Let’s say you have a boundary in use that is completely empty,
and you want to stop using that partition, to free it up for some reason, then you want to use the MERGE
operator. The syntax is just like SPLIT, except the boundary point you pass will be removed from your
PARTITION FUNCTION
Note: Merge will not remove physical filegroup from the database structure, it just do merging of two
different sets into one
So let’s go now to MERGE boundary ’2009-01-01′ we will work on the Example of RANGE RIGHT
ALTER PARTITION FUNCTION PF_DBForPartitioning_RangeRight() MERGE RANGE('2009-01-01')
Now to check what happened for the boundary_value and our Partitioning Function you will found Filegroup
FG3 is merged with FG2 this meaning FG3 is deleted?? NO filegroup still exist but not used in this Function

Execute our main SP to check the Table partitioning after MERGE operator
Exec PartitionTableDetail 'Partitioning_RangeRight'
Compare Partition function Syntax before MERGE and after MERGE
 Before MERGE
CREATE PARTITION FUNCTION PF_DBForPartitioning_RangeRight (datetime)
AS RANGE RIGHT FOR VALUES ( '2008-01-01','2009-01-01', '2010-01-01');

After MERGE
CREATE PARTITION FUNCTION [PF_DBForPartitioning_RangeRight](datetime)
AS RANGE RIGHT FOR VALUES (N'2008-01-01T00:00:00.000', N'2010-01-01T00:00:00.000')
GO
Split
Adds one partition to the partition function. boundary_value determines the range of the new partition, and
must differ from the existing boundary ranges of the partition function. Based on boundary_value, the
Database Engine splits one of the existing ranges into two. Of these two, the one where the new
boundary_value resides is considered the new partition.
At the first I will ALTER PARTITION SCHEME to Adds a filegroup to a partition scheme or alters the
designation of the NEXT USED filegroup for the partition scheme.

Make a new partition filegroup available to the partition scheme
ALTER PARTITION SCHEME PS_DBForPartitioning_RangeRight
NEXT USED [FG3]
;

Add a new partition (which will use the filegroup identified as “next used”)
ALTER PARTITION FUNCTION PF_DBForPartitioning_RangeRight()
SPLIT RANGE ('2009-01-01')
Now View information about the partitions and partitioned data I write in this series more scripts about this
part so you can view this information by the our stored Procedure PartitionTableDetail or by the below new
Script
SELECT
N'DatabaseName' = DB_NAME()
, N'SchemaName' = s.name
, N'TableName' = o.name
, N'IndexName' = i.name
, N'IndexType' = i.type_desc
, N'PartitionScheme' = ps.name
, N'DataSpaceName' = ds.name
, N'DataSpaceType' = ds.type_desc
, N'PartitionFunction' = pf.name
, N'PartitionNumber' = dds.destination_id
, N'BoundaryValue' = prv.value
, N'RightBoundary' = pf.boundary_value_on_right
-- 1 = TRUE (values are less than boundary)
-- 0 = FALSE (values are less than or equal to boundary)
, N'PartitionFileGroup' = ds2.name
, N'RowsOfData' = p.[rows]
FROM
sys.objects AS o
INNER JOIN sys.schemas AS s
ON o.[schema_id] = s.[schema_id]
INNER JOIN sys.partitions AS p
ON o.[object_id] = p.[object_id]
INNER JOIN sys.indexes AS i
ON p.[object_id] = i.[object_id]
AND p.index_id = i.index_id
INNER JOIN sys.data_spaces AS ds
ON i.data_space_id = ds.data_space_id
LEFT OUTER JOIN sys.partition_schemes AS ps
ON ds.data_space_id = ps.data_space_id
LEFT OUTER JOIN sys.partition_functions AS pf
ON ps.function_id = pf.function_id
LEFT OUTER JOIN sys.partition_range_values AS prv
ON pf.function_id = prv.function_id
AND p.partition_number = prv.boundary_id
LEFT OUTER JOIN sys.destination_data_spaces AS dds
ON ps.data_space_id = dds.partition_scheme_id
AND p.partition_number = dds.destination_id
LEFT OUTER JOIN sys.data_spaces AS ds2
ON dds.data_space_id = ds2.data_space_id
WHERE
s.name = N'dbo' -- schema name
AND o.name = N'Partitioning_RangeRight' -- table name
ORDER BY
DatabaseName
, SchemaName
, TableName
, IndexName
, PartitionNumber
;