I've previously written about how you can find indexes that are not being used and get their sizes. Not being allowed to reuse that meant that I had to come up with something else.
In my previous post on calculating replication schema options I documented a way of being able to change article options in transactional replication so that you could apply all the non-clustered indexes on your subscribing table that exist on the publishing one. But what if you are using replication to offload reporting and you need to create indexes that don't exist on the publishing table?
You could always manually apply these indexes any time that you perform a snapshot but this requires manual work and can easily be forgotten.
Fortunately there is another option, you can have replication automatically apply a post-snapshot SQL script which will create those indexes for you. Here's how...
Create a basic publication (snapshot or transactional) and add a table article. Perform the snapshot and compare indexes between the tables (in this example I am using the person.address table from AdventureWorks2008).
After the snapshot here's how the indexes stand
For this example we're going to create a new index on Admindb.person.address. To do this first we need to generate the index creation script
IF NOT EXISTS (SELECT * FROM sys.indexes WHERE object_id = OBJECT_ID(N'[person].[address]') AND name = N'NCIX_Zip')
CREATE NONCLUSTERED INDEX [NCIX_Zip] ON [person].[address]
WITH (ONLINE = ON, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
Save this script to C:\ReplicationScripts\CreateReportingIndex.sql
Now we change the existing publication so that whenever a snapshot is taken it will apply this script when applied to the subscriber. This change can be done in a couple of ways.
The quick and easy way is to use sp_changepublication and just pass in the publication name, property change and location of the script.
@publication = 'Post Snapshot Test'
, @property = N'post_snapshot_script' ,
@value = 'C:\ReplicationScripts\CreateReportingIndex.sql'
, @force_invalidate_snapshot = 1 --must invalidate existing snapshots for this to take effect
This can also be done using the GUI (right click on the publication and select Properties)
When you next perform a snapshot then the script will be applied. We can check that this actually worked first by looking at replication monitor where it will tell you that the script was applied.
And then you can check the table itself and confirm that the index exists
There are a couple of final things to note.
Usually you will specify a unc path for the SQL script so that you just have to maintain a single copy. You just need to ensure that the subscriber is able to access the post-snapshot script location.
Post-snapshots are not limited to creating indexes, in fact you can do pretty much anything just so long as the Distribution Agent has the access;
- Send yourself an email to let you know that the snapshot has been applied on the subscriber
- Apply table permissions
- Create views
If you use replication and find yourself manually reapplying indexes it's worth evaluating whether using post-snapshot scripts might save you some work.