Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find what foreign key references an index on table

Tags:

sql

sql-server

I have a non clustered index I would like to drop (it is a duplicate of the clustered index). However, it is being used by a foreign key constraint. I would like to be able to identify which constraint is using the index, so I can update it to use the primary key index.

When I try to drop it:

DROP INDEX [idx_duplicate] ON [dbo].[MyTable]

I get an error:

An explicit DROP INDEX is not allowed on index 'dbo.MyTable.idx_duplicate'. It is being used for FOREIGN KEY constraint enforcement.

I tried to find the culprit with the following query but no luck:

SELECT name
FROM sys.foreign_keys
WHERE OBJECT_NAME (referenced_object_id) = 'idx_duplicate'
like image 668
brianfeucht Avatar asked Sep 09 '13 21:09

brianfeucht


People also ask

How do you find the value of foreign key in a table?

If you are inserting data into a dependent table with foreign keys: Each non-null value you insert into a foreign key column must be equal to some value in the corresponding parent key of the parent table. If any column in the foreign key is null, the entire foreign key is considered null.

Is index associated with foreign key?

MySQL requires that foreign key columns be indexed; if you create a table with a foreign key constraint but no index on a given column, an index is created. Information about foreign keys on InnoDB tables can also be found in the INNODB_FOREIGN and INNODB_FOREIGN_COLS tables, in the INFORMATION_SCHEMA database.

How can I tell which index a table is using?

To see the index for a specific table use SHOW INDEX: SHOW INDEX FROM yourtable; To see indexes for all tables within a specific schema you can use the STATISTICS table from INFORMATION_SCHEMA: SELECT DISTINCT TABLE_NAME, INDEX_NAME FROM INFORMATION_SCHEMA.


3 Answers

Something like

Select
    f.name,
    object_name(f.parent_object_id)
From
    sys.foreign_keys f
        inner join
    sys.indexes i
        on f.referenced_object_id = i.object_id and
           f.key_index_id = i.index_id
Where
    i.name = 'idx_duplicate' and
    i.object_id = object_id('[dbo].[MyTable]')
like image 131
Laurence Avatar answered Oct 12 '22 08:10

Laurence


This will tell you the tables, the foreign key and the columns involved:

select f.name
  , parentTable = o.name
  , parentColumn = c.name
  , foreignTable = ofr.name
  , foreignColumn = cfr.name
from sys.foreign_keys f
  inner join sys.foreign_key_columns fc on f.object_id = fc.constraint_object_id
  inner join sys.objects o on fc.parent_object_id = o.object_id
  inner join sys.columns c on fc.parent_column_id = c.column_id
    and o.object_id = c.object_id
  inner join sys.objects ofr on fc.referenced_object_id = ofr.object_id
  inner join sys.columns cfr on fc.referenced_column_id = cfr.column_id
    and ofr.object_id = cfr.object_id
  inner join sys.indexes i on ofr.object_id = i.object_id
where i.name = 'MyIndex'

SQL Fiddle with demo.

like image 27
Ian Preston Avatar answered Oct 12 '22 08:10

Ian Preston


I realize that this post is a couple of years old but I wouldn't drop any such index without digging into it a LOT deeper. The non-clustered index is NOT the same as the clustered index even if the key columns are identical. The Leaf Level of the NCI is MUCH more narrow than the Leaf Level of the CI and, therefor, contains many more rows of information per page than the CI. You may actually be causing a performance problem (especially for inserts on the other table) by dropping the NCI.

like image 3
Jeff Moden Avatar answered Oct 12 '22 08:10

Jeff Moden