Running a SP with partition in SQL Server - sql-server

In a Stored Procedure we are using partition function. The job runs based on the period like '202001','202002' etc. For previous periods the SP was executed and now due to some data issues we are thinking to execute the SP for previous periods.
We are actually loading data into a Work Table and using partition we are switching data from Work table to main table
ALTER TABLE db_table_Work switch
TO db_table partition $PARTITION.db_table_PFPerPost(#PeriodKey);
If we execute the SP now again for past period, will it cause the data to insert again for existing rows? Or will it insert the newly updated data?

SWITCH will err if the target partition is not empty. Furthermore, the non-partitioned source table must have a check constraint on the partitioning column to ensure all rows fall within the target boundary.
If data will exist in the primary table partition during reprocessing, you'll need to ensure data in the replaced partition is not changed during reprocessing of previous periods to avoid data loss. If that is not possible, a MERGE is needed to insert/update/delete rows instead of the more efficient SWITCH.
Consider partitioning the work table using the same partition scheme as the target table to avoid the need for a check constraint. This will also facilitate moving the partition into the work table and switching back after reprocessing. Below is an example of this technique, which assumes it is acceptable for the primary table partition to be empty during reprocessing of the period:
--switch primary table partiton into work table for reprocessing
ALTER TABLE db_table
SWITCH PARTITION $PARTITION.db_table_PFPerPost(#PeriodKey)
TO db_table_Work PARTITION $PARTITION.db_table_PFPerPost(#PeriodKey);
--reprocess data here
--switch reprocessed data back into primary table
ALTER TABLE db_table_Work
SWITCH PARTITION $PARTITION.db_table_PFPerPost(#PeriodKey)
TO db_table PARTITION $PARTITION.db_table_PFPerPost(#PeriodKey);

Related

How do I add a new SQL Server partition range to house future data without altering the existing data locations?

Several years ago I partitioned a collection of very large columnstore indexed tables. For simplicity, let's say I have four partition files where data is stored based on ranges of customer ID.
CREATE PARTITION FUNCTION [CustomerPF](int) AS RANGE LEFT FOR VALUES (
N'25'
,N'50'
,N'75')
CREATE PARTITION SCHEME [CustomerPS] AS PARTITION [CustomerPF] TO (
customer0to25fg
,customer26to50fg
,customer51to75fg
,customer76plusfg
CREATE CLUSTERED COLUMNSTORE INDEX [CCI_GiantTable] ON [schema].[GiantTable] ON [CustomerPS]([CustomerId])
Now let's say I would like to create space, in advance, for customers 100 and above. I tried to do it like this:
ALTER PARTITION SCHEME CustomerPS NEXT USED customer100plusfg
ALTER PARTITION FUNCTION [CustomerPF]() SPLIT RANGE (100)
But I get the following error:
SPLIT clause of ALTER PARTITION statement failed because the partition
is not empty. Only empty partitions can be split in when a
columnstore index exists on the table. Consider an ALTER TABLE SWITCH
operation from one of the nonempty partitions on the source table to a
temporary staging table and then re-attempt the ALTER PARTITION SPLIT
operation. Once completed, use ALTER TABLE SWITCH to move the staging
table partition back to the original source table.
I was hoping that, because I do not yet have a customerID of 100 or greater that I would be allowed to add a new partition without having to alter the columnstore tables themselves. How do I add a new partition for customers 100-n? Is it possible to do this without moving all the data for "customer75plus"? There are a lot of large columnstore tables in these partitions and moving data around is not all that feasible.
The new partition you create with SPLIT contains the split point. So you are trying to create a new partition (75-100]. But the partition (75-MaxVal] contains data.
Instead use a RANGE RIGHT partition scheme, so when you split the new partition is on the end so you can split anywhere above the current max value.
With RANGE LEFT you would have to always maintain an empty partition on the end to split.

How to drop a partition of a table before 6 months ago

There is a table in my database and I will create a partition for this table each day, the rows for each day are nearly 10e7.
Is there a way to drop the oldest partition directly?
Because I got in trouble with switch the oldest partition to a new table, the code is shown as below:
alter table dbo.TempData switch partition 1 to dbo.TempCleanBuffer
My SQL Server always reminds me that the two Clustered Indexes of the two tables are not identically after I execute the code. I've already created the new table on the same filegroup with the partition I want to switch.
If I can't drop the partition directly, how can I fix the problem properly?

Table Partitioning incomplete in sql server2012

I have a large table which contains 83 million records in it.
There is a column called 'TradingDateKey' based on which the table is partitioned.
Below are the partition schema and partition functions :
CREATE PARTITION SCHEME [ps__fac_sale] AS PARTITION [pf__fac_sale] TO
([fg__fac_sale__2005], [fg__fac_sale__2006], [fg__fac_sale__2007],
[fg__fac_sale__2008], [fg__fac_sale__2009], [fg__fac_sale__2010],
[fg__fac_sale__2011], [fg__fac_sale__2012], [fg__fac_sale__2013],
[fg__fac_sale__2014])
GO
CREATE PARTITION FUNCTION pf__fac_sale AS RANGE LEFT FOR VALUES
(20050630, 20060630, 20070630, 20080630, 20090630, 20100630, 20110630,
20120630, 20130630)
GO
As you can see there are no partitions after 20130630 to 20150915.
The problem is that We have a query given by our client to run against the
above table whihc also uses some joins and it
is taking long time to execute .
can you please let me know the best possible way to fix this. Can we alter the
partition function and schema and rebuild indexes or it has to be complete
reload of data into another table with proper partition function & schema?.
Your help is appreciated .Thank you
You can adjust the partition function and scheme without rebuilding the table. Check out alter partition function and alter partition scheme syntax over at Microsoft's website. The basic syntax is:
alter partition function pf__fac_sale() split range (newrangevalue);
go
alter partition scheme ps__fac_sale next used [filegroup]

Permanently sorting a table in SQLServer based on pre-existing data

I have made a table in SQL Server based on pre-existing data:
SELECT pre_existing_data
INTO new_table
FROM existing_table
I am trying to get the output to permanently sort by a particular field once the table is created. I thought this would be as simple as adding an ORDER BY clause at the end of the chunk of code that makes the table, but the data still won't sort properly.
There is no way to permanently sort a table in SQL.
You can create an index on the table and queries which use the index (in an ORDER BY clause) will be returned quicker, but the order the data is stored on the disk is not controllable.
You can create an index-organized table by using a CLUSTERED INDEX, which stores the data on disk in an ordered fashion on the clustering key. Then if you ORDER BY in your query based on the clustering key, data should come out very fast. Note that you have to use the ORDER BY in your query no matter what.
I have made a new table on SQL Server on pre-existing Schema
insert into new_table
select * from old_table
ORDER BY col ASC|DSC;
After it drop old_table and rename new table to old_table_name
drop table old_table_name;
rename new_table_name to old_table_name;
Try this trick to short your data in the table permanently

SQL Server 2005: Aligning indexes with partitioned table

I'm attempting to align an index with a partitioned table, but the partition key column is nullable in the table definition.
In order to align the indexes I have to make this field not null, but when I attempt to alter the column on the table I receive an error saying that the table depends on that field.
You will need to remove the partition scheme from that table, correct the data issue, then repartition.
Or, create a new, properly partitioned version of the table with the right constraints and put your data into it from the old table.

Resources