Search code examples
sql-server-2008synonym

SQL Server 2008: Disabling all indexes for a synonym


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'

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