Question

I have two identical tables, each mapped to a staging and production synonym. Our daily process is that staging is truncated, new data inserted, then we swap synonyms. To speed this up some, I'd like to disable all indexes on the staging synonym. The example in the link below is pretty close to what I need, but it's for tables not synonyms.

Disable all non-clustered indexes

The only method I've found to jump from the base object name in the synonyms table to getting the actual object_id of the base table in the objects table is using the replace() function in the script below. This seems decidedly dangerous coding, so I'm asking if there's another safer way that I'm missing.

select
    s1.name,
    s1.base_object_name,
    o1.object_id
from
    sys.synonyms s1
left join
    sys.objects o1
ON
    o1.name = replace(REPLACE(s1.base_object_name,'[database].[dbo].[',''),']','')
where
s1.name = 'synonym_name'
Was it helpful?

Solution

Below is the code I came up with and I hope should be fairly self-explanatory.

CREATE PROCEDURE synonym_index_disable
@db_name varchar(max),
@schema_name varchar(max),
@synonym varchar(max)

AS

DECLARE @sql AS VARCHAR(MAX)='';
DECLARE @fq_name varchar(max);

SET @fq_name = '[' + @db_name + '].[' + @schema_name + '].[';

SELECT @sql = @sql + 
'ALTER INDEX ' + sys.indexes.name + ' ON  ' + sys.objects.name + ' DISABLE;' +CHAR(13)+CHAR(10)
FROM 
    sys.indexes
JOIN 
    sys.objects
    ON sys.indexes.object_id = sys.objects.object_id
LEFT JOIN
    sys.synonyms
ON
    sys.objects.name = replace(REPLACE(sys.synonyms.base_object_name,@fq_name,''),']','')
WHERE
    sys.indexes.type_desc = 'NONCLUSTERED' AND
    sys.objects.type_desc = 'USER_TABLE' AND
    sys.synonyms.name = @synonym

EXEC(@sql);


GO
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top