2010-02-22 3 views
7

Visto come foreign key does not automatically create an index in SQL Server, voglio creare un indice esplicito su ogni campo FK nel mio database. E ho più di 100 tabelle nello schema ...Script per aggiungere un indice su ogni chiave esterna?

Quindi, qualcuno ha uno script già pronto che posso usare per rilevare tutti gli FK e creare un indice su ciascuno?

+1

Heh, l'ho fatto uno nel fine settimana e l'ho scartato. È stato personalizzato in base alla convenzione di denominazione, quindi ho apportato molta manipolazione delle stringhe e selezionato da sys.foreign_keys con schema_name (schema_id) e object_name (parent_object_id). –

risposta

7

OK, ho lavorato questo fuori me stesso - qui è per tutti gli altri benefici ...

select 'create index IX_'+c.name+'_'+p.name+' on '+c.name+'('+cf.name+');' 
from sysforeignkeys fk join sysobjects c on fk.fkeyid=c.id 
join sysobjects p on fk.rkeyid=p.id 
join syscolumns cf on c.id=cf.id and cf.colid = fk.fkey 
left join sysindexkeys k on k.id = cf.id and k.colid = cf.colid 
where k.id is null 
order by c.name 

Non funziona al 100%, come ad esempio se si hanno due FKS su un tavolo allo stesso tabella primaria, ma ci sono poche istanze di questo (almeno nel mio DB) che potrei correggerle in modo pratico a mano.

3

Ho modificato la query per utilizzare le visualizzazioni di sistema. Scriverà inoltre ogni FK nella tabella non solo uno.

SELECT 'CREATE NONCLUSTERED INDEX ndx_' + o.name + '__' + c.name 
    + ' ON ' + o.name + ' (' + c.name + ')' 
FROM sys.foreign_keys  fk 
JOIN sys.objects    o ON fk.parent_object_id = o.object_id 
JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id 
JOIN sys.columns    c ON fkc.parent_object_id = c.object_id 
           AND fkc.parent_column_id = c.column_id 
ORDER BY o.name 
+0

Questo è bello, aggiungerò le braquette quadrate attorno ai nomi nel caso qualcuno abbia nominato un utente di una colonna (mi è appena successo). – vercelli

6

Ok, ecco la mia opinione su questo. Ho aggiunto il supporto per gli schemi e anche verificare se esiste un indice con la convenzione di denominazione corrente. In questo modo mentre modifichi le tue tabelle puoi controllare gli indici mancanti.

SELECT 'CREATE NONCLUSTERED INDEX IX_' + s.NAME + '_' + o.NAME + '__' + c.NAME + ' ON ' + s.NAME + '.' + o.NAME + ' (' + c.NAME + ')' 
    FROM sys.foreign_keys fk 
    INNER JOIN sys.objects o ON fk.parent_object_id = o.object_id 
    INNER JOIN sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id 
    INNER JOIN sys.columns c ON fkc.parent_object_id = c.object_id 
     AND fkc.parent_column_id = c.column_id 
    INNER JOIN sys.tables t ON t.object_id = o.object_id 
    INNER JOIN sys.schemas s ON s.schema_id = t.schema_id 
    LEFT JOIN sys.indexes i ON i.NAME = ('IX_' + s.NAME + '_' + o.NAME + '__' + c.NAME) 
    WHERE i.NAME IS NULL 
    ORDER BY o.NAME 
+0

Questo è fantastico, grazie per la pubblicazione. – udog