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'
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