Redistributing data

If you need to redistribute data on partitions, your choice of method depends on how much space the data occupies on the partition. If the space the table occupies is less than 40 to 45% of the space in the segment, you can create a clustered index to redistribute the data.

If the table occupies more than 40 to 45% of the space on the segment, you need to bulk copy the data out, truncate the table, and copy the data in again. The steps you take depend on whether you need a clustered index and whether the data is already in clustered key order.

Use sp_helpsegment and sp_spaceused to see if there is room to create a clustered index on the segment.


If there is enough space to create or re-create the clustered index

If there is enough space, see “Distributing data evenly across partitions” for the steps to follow. If you do not need the clustered index, you can drop it without affecting the data distribution.

Dump the database after creating the clustered index.


If there is not enough space on the segment, but space exists elsewhere on the server

If there is enough space for a copy of the table, you can copy the table to another location and then re-create the clustered index to copy the data back to the target segment.

The steps vary, depending on the location of the temporary storage space:


Using the default segment or tempdb

  1. Use select into to copy the table to the default segment or to tempdb.

    select * into temp_sales from sales
    

    or

    select * into tempdb..temp_sales from sales
    
  2. Drop the original table.

  3. Partition the copy of the table.

  4. Create the clustered index on the segment where you want the table to reside.

  5. Use sp_rename to change the table’s name back to the original name.

  6. Dump the database.


Using space on another segment

If there is space available on another segment:

  1. Create a clustered index, specifying the segment where the space exists. This moves the table to that location.

  2. Drop the index.

  3. Re-create the clustered index, specifying the segment where you want the data to reside.

  4. Dump the database.


If there is not enough space to re-create the clustered index

If there is not enough space, and you need a to re-create a clustered index on the tables:

  1. Copy out the data using bulk copy.

  2. Unpartition the table.

    See “alter table...unpartition Syntax”.

  3. Truncate the table with truncate table.

  4. Drop the clustered index using drop index or alter table...drop constraint.

    Then, drop nonclustered indexes, to avoid deadlocking during the parallel bulk copy sessions.

    See “Distributing data evenly across partitions”.

  5. Repartition the table.

    See “alter table...partition syntax”.

  6. Copy the data into the table using parallel bulk copy. You must take care to copy the data to each segment in index key order, and specify the number of rows for each partition to get good distribution.

    See “Using parallel bcp to copy data into partitions”.

  7. Re-create the index using the with sorted_data and on segment_name clauses. This command performs a serial scan of the table and builds the index tree, but does not copy the data.

    Do not specify any of the clauses that require data copying (fillfactor, ignore_dup_row, and max_rows_per_page).

  8. Re-create any nonclustered indexes.

  9. Dump the database.


If there is not enough space, and no clustered index is required

If there is no clustered index, and you do not need to create one:

  1. Copy the data out using bulk copy.

  2. Unpartition the table.

    See “alter table...unpartition Syntax”.

  3. Truncate the table with truncate table.

  4. Drop nonclustered indexes, to avoid deadlocking during the parallel bulk copy in sessions.

  5. Repartition the table.

    See “alter table...partition syntax”.

  6. Copy the data in using parallel bulk copy.

    See “Using parallel bcp to copy data into partitions”.

  7. Re-create any nonclustered indexes.

  8. Dump the database.


If there is no clustered index, not enough space, and a clustered index is needed

To change index keys on the clustered index of a partitioned table, or if you want to create an index on a table that has been stored as a heap, performing an operating system level sort can speed the process.

Creating a clustered index requires 120% of the space used by the table to create a copy of the data and build the index tree.

If you have access to a sort utility at the operating system level:

  1. Copy the data out using bulk copy.

  2. Unpartition the table.

    See “alter table...unpartition Syntax”.

  3. Truncate the table with truncate table.

  4. Drop nonclustered indexes, to avoid deadlocking during the parallel bulk copy in sessions.

  5. Repartition the table.

    See “alter table...partition syntax”.

  6. Perform an operating system sort on the file.

  7. Copy the data in using parallel bulk copy.

    See “Using parallel bcp to copy data into partitions”.

  8. Re-create the index using the sorted_data and on segment_name clauses. This command performs a serial scan of the table and builds the index tree, but does not copy the data.

    Do not specify any of the clauses that require data copying (fillfactor, ignore_dup_row, and max_rows_per_page).

  9. Re-create any nonclustered indexes.

  10. Dump the database.