I have table which has 600 million records and also has the Partition on PS_TRPdate(TRPDate) column, I want to change it to another Partition PS_LPDate(LPDate).
So I have tried with small amount of data with following steps.
1) Drop the Primary key Constraints.
2) Adding the New Primary Key Clustered Index with new Partition PS_LPDate(LPDate).
Is it Feasible with 600 million records? Can anyone guide me for it?
and How does it works with Non Partitioned Tables?
--343
My gut feeling is that you should create a parallel table using a new primary key, file groups and files.
To test out my assumption, I looked at a old blog post in which I stored the first five million prime numbers into three files / file groups.
I used the TSQL view that Kalen Delaney wrote and I modified to my standards to look at the partition information.
As you can see, we have three partitions based on the primary key.
Next, I drop the primary key on the my_value column, create a new column named chg_value, update it to the prime number, and then try to create a new primary key.
-- drop primary key (pk)
alter table tbl_primes drop constraint [PK_TBL_PRIMES]
-- add new field for new pk
alter table tbl_primes add chg_value bigint not null default (0)
-- update new field
update tbl_primes set chg_value = my_value
-- try to add a new primary key
alter table tbl_primes add constraint [PK_TBL_PRIMES] primary key (chg_value)
First, I was surprise that the partition still stayed together after dropping the PK. However, the view shows the index no longer exists.
Second, I end up receiving the following error during constraint creation.
While you could merge/switch the partitions into one file group which is not part of the scheme, drop/create the primary key, partition function & partition scheme, and then move the data yet again with the appropriate merge/switch statements, I would not.
This will generate a ton of work (TSQL) and cause alot of I/O on the disks.
I suggest you build a parallel partitioned table, if you have space, with the new primary key. Reload the data from the old table to the new.
If you are not using data compression and have the enterprise version of SQL Server, why not save the bytes by turning it on.
Good luck!
John
www.craftydba.com
Related
I ran into a curious problem. I am creating copies of currently existing tables and adding partitions to them.
The process is as follows:
Rename current constraints (can't drop them without dropping table itself because I will need data later)
Create a new partitioned table that structurally copies current one.
so I have MYTABLE (original) and PART_TABLE (new partitioned), including FKs
Copy data with INSERT INTO SELECT clause
Alter table with indexes and PKs
Rename tables so I end up with MYTABLE (new partitioned) and TRASH_TABLE (original)
In step 4 unfortunately, I got an error
ALTER TABLE MYTABLE ADD CONSTRAINT "PK_MYTABLE"
PRIMARY KEY ("MY_ID", "SEQUENCE")
USING INDEX LOCAL TABLESPACE INDEXSPACE;
SQL Error: ORA-00955: "name is already used by an existing object"
Now, I logically assumed that I simply forgot to rename the PK so I check TRASH_TABLE, but I see there the correctly renamed PK.
I also ran
SELECT *
FROM ALL_CONSTRAINTS
WHERE CONSTRAINT_NAME LIKE 'PK_MYTABLE'
and it returned 0 results. Same with table USER_CONSTRAINTS.
Renamed PKs are displaying correctly.
Another thing I noticed is that only PKs are locked this way. Adding FKs or UNIQUE constraints work just fine.
As stated in How to rename a primary key in Oracle such that it can be reused, the problem is that Oracle creates an index for the primary key. You need to rename the autogenerated index as well. As suggested by Tony Andrews, try
ALTER INDEX "PK_MYTABLE" RENAME TO "PK_MYTABLE_OLD";
I have a very large sales detail table in our DataWarehouse.
It has 5-7 nonclustered indexes, all partition aligned on date.
The clustered index is just on the date column.
I also have one nonclustered primary key set on an identity column.
If I want to do any form of partition swapping, I have to drop the primary key, then rebuild it when I am done.
Is there some other way to enforce the primary key while allowing me to swap partitions quickly? I want to swap out a partition to do processing on it, and this rebuild is unfortunately making that more time consuming then necessary.
I was considering adding saledate to the primary key, and then potentially making a unique constraint on the primary key column...but if I'm understanding correctly, a unique constraint just creates another nonclustered index that wouldn't be partition aligned.
Is there a solution to this, or do I have to suck it up and wait it out?
I have a Mircrosoft Sql Server database made up of about 8 tables that are all related that I am trying to update. To do this I create a number of temporary tables
"CREATE TABLE [vehicle_data].[dbo].[temp_MAINTENANCE_EVENT] (" +
"[maintenance_event_id] int," +
"[maintenance_computer_code_id] int," +
"[veh_eng_maintenance_id] int," +
"CONSTRAINT [PK_maintenance_event_id"] PRIMARY KEY CLUSTERED ([maintenance_event_id] ASC))";
Then after all the temporary tables have been created I drop the existing tables, rename the temporary tables, and add foreign keys and indexing to the new tables to speed up joins and querying.
The issue I'm having is the original primary key references are remaining. So when I go to update again I get
Exception: There is already an object named 'PK_maintenance_event_id'
in the database. Could not create constraint.
I'm wondering what is the best course of action is? Should I not set the primary key when I create the temporary table and instead add it to the table after it has been renamed? Or is there a way to rename constraints so that when I rename the table I can change the name of the primary key constraint.
After the original tables have been dropped I want there to be as little downtime as possible, but anything that happens before the tables have been dropped can take a really long time and it won't matter.
If your temp tables need that constraint
When create
use
CONSTRAINT [PK_maintenance_event_id_temp"]
instead of
CONSTRAINT [PK_maintenance_event_id]
when you rename temp back to real table
exec sp_rename [PK_maintenance_event_id_temp], [PK_maintenance_event_id]
I have to insert data into a table that has a PK in it. I also have another table that has a clustered index in it.
Should I drop the PK or the INDEX for the the best INSERT speeds? Then recreate them afterwards?
I load data to these types of tables on a routine basis and I want to make sure I am using the quickest way possible in all situations.
A primary key uniquely identifies a record and has other uses as well. An index makes select queries run faster.
You should never drop your primary key.
Whether or not you drop and re-create indexes when adding records depends on the circumstances.
Primary Key : Uniquely identifies the the data & we cannot insert duplicate Data.
Index : Index help us to get out data to us very quickly.
Very Important Concept about Primary key & Index
Suppose your column is marked with the primary key then Clustered Index automatically gets created,
If no clutstered index is already present in the table
To See that Your Index is Created Successfully, You can use.
sp_helpindex Index_Name
- About Index :
You cannot create a unique index on a single column if that column contains NULL in more than one row. Similarly, you cannot create a unique index on multiple columns if the combination of columns contains NULL in more than one row. These are treated as duplicate values for indexing purposes.
- About Primary Key :
All columns defined within a PRIMARY KEY constraint must be defined as NOT NULL. If nullability is not specified, all columns participating in a PRIMARY KEY constraint have their nullability set to NOT NULL.
There is one column named Line_no (smallint) now. I want to change this column data type is bigint ,but this column is primary key, and have so many tables has foreign key reference on it, so how to change it?, i need to change both Sql server and oracle database
First of all there's no easy way to do that currently. especially in Oracle, in order to change the data type, all the values of the field should be null. anyway the following process works for both Oracle and SQL Server:
make your database off line so that no operation can disturb our
process.
Add a new field, say line_num having your new data type.
update the the new field with the line_no values for all records.
write a Stored Procedure to drop all the FKs referencing current
PK, using meta data and this SP should write the add FK command to
dbms output, while it is looping, so that later you can execute them
to add these FKs again in step 9.
drop the primary key off the line_no field.
drop the field line_no.
rename the field
line_num to line_no.
add the primary key on the new field.
run the commands generated in step 4 to add all the FKs again.
make your db online :)
It depends on your DBMS. You may have to drop the foreign key constraints, alter the columns and re-create the constraints.