كيف يمكنني العثور على المفاتيح الخارجية غير معدلة في SQL Server

StackOverflow https://stackoverflow.com/questions/1406119

سؤال

ولدي قاعدة بيانات SQL Server 2000 مع ما يقرب من 220 الجداول. هذه الجداول لديها عدد من علاقات المفاتيح الخارجية بينهما. من خلال تحليل الأداء، اكتشفنا عددا من هذه علاقات المفاتيح الخارجية والفهارس في عداد المفقودين. بدلا من أن يكون رد الفعل لمشاكل الأداء، أود أن يكون نشاطا وتجد كل المفاتيح الخارجية التي يتم الفهارس في عداد المفقودين.

وكيف يمكنني برمجيا تحديد أي مفتاح الأجنبية الفهارس مفقودة؟

هل كانت مفيدة؟

المحلول 2

وهنا هو الجواب الذي يعمل ل SQL Server 2000 من تأليف زميل في العمل:

/*
Description:
    This script outputs a table with all the current database un-indexed foreign keys.

    The table has three columns ( TableName , ColumnName, ForeignKeyName ) 
    TableName: The table containing the un-indexed foreign key
    ColumnName: The foreign key column that’s not indexed 
    ForeignKeyName: Name of foreign key witch column doesn’t have an index 
    */
DECLARE 
    @TableName varchar(255),
    @ColumnName varchar(255),
    @ForeignKeyName sysname

SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

DECLARE FKColumns_cursor CURSOR Fast_Forward FOR
SELECT  cu.TABLE_NAME, cu.COLUMN_NAME, cu.CONSTRAINT_NAME
FROM    INFORMATION_SCHEMA.TABLE_CONSTRAINTS ic 
    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE cu ON ic.CONSTRAINT_NAME = cu.CONSTRAINT_NAME
WHERE   ic.CONSTRAINT_TYPE = 'FOREIGN KEY'

CREATE TABLE #temp1(    
    TableName varchar(255),
    ColumnName varchar(255),
    ForeignKeyName sysname
)

OPEN FKColumns_cursor  
FETCH NEXT FROM FKColumns_cursor INTO @TableName, @ColumnName, @ForeignKeyName

WHILE @@FETCH_STATUS = 0  
BEGIN

    IF ( SELECT COUNT(*)
    FROM    sysobjects o    
        INNER JOIN sysindexes x ON x.id = o.id
        INNER JOIN  syscolumns c ON o.id = c.id 
        INNER JOIN sysindexkeys xk ON c.colid = xk.colid AND o.id = xk.id AND x.indid = xk.indid
    WHERE   o.type in ('U')
        AND xk.keyno <= x.keycnt
        AND permissions(o.id, c.name) <> 0
        AND (x.status&32) = 0
        AND o.name = @TableName
        AND c.name = @ColumnName
    ) = 0
    BEGIN
        INSERT INTO #temp1 SELECT @TableName, @ColumnName, @ForeignKeyName
    END


    FETCH NEXT FROM FKColumns_cursor INTO @TableName, @ColumnName, @ForeignKeyName
END  
CLOSE FKColumns_cursor  
DEALLOCATE FKColumns_cursor 

SELECT * FROM #temp1 ORDER BY TableName

نصائح أخرى

SELECT  *
FROM    sys.foreign_keys fk
WHERE   EXISTS
        (
        SELECT  *
        FROM    sys.foreign_key_columns fkc
        WHERE   fkc.constraint_object_id = fk.object_id
                AND NOT EXISTS
                (
                SELECT  *
                FROM    sys.index_columns ic
                WHERE   ic.object_id = fkc.parent_object_id
                        AND ic.column_id = fkc.parent_column_id
                        AND ic.index_column_id = fkc.constraint_column_id
                )
        )

وأنا لم يكن لديك نسخة من SQL Server 2000 مفيد، ولكنك قد تحتاج إلى تغيير sys.foreign_key إلى sysforeignkeys الخ، مثل وصفه <لأ href = "http://msdn.microsoft.com/library/ms187997(SQL.90 ) .ASPX "يختلط =" noreferrer "> here .

وهذا الاستعلام يختار كل المفاتيح الخارجية التي لم يكن لديك مؤشر تغطي جميع الأعمدة التي تشكل المفتاح.

وهذا يدعم بأعمدة المفاتيح الخارجية فقط كذلك.

وهذا، ومع ذلك، سيعود إيجابية كاذبة إذا كان هناك مؤشر مركب يشمل جميع أعمدة ولكنها ليست في أقصى اليسار الأعمدة في هذا المؤشر.

ومثل، إذا كان هناك FOREIGN KEY (col2, col3) وفهرس على (col1, col2, col3)، وهذا سيعود بأن هناك مؤشر على الرغم من هذا مؤشر غير قابل للاستخدام لهذا المفتاح الخارجي.

وبنيت على رمز أعلاه لإسقاط جدول مؤقت والحصول على مخطوطات لإنشاء الفهارس.

   /*
Description:

    */
DECLARE 
    @SchemaName varchar(255),
    @TableName varchar(255),
    @ColumnName varchar(255),
    @ForeignKeyName sysname

SET NOCOUNT ON
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

DECLARE FKColumns_cursor CURSOR Fast_Forward FOR
SELECT  cu.TABLE_SCHEMA, cu.TABLE_NAME, cu.COLUMN_NAME, cu.CONSTRAINT_NAME
FROM    INFORMATION_SCHEMA.TABLE_CONSTRAINTS ic 
    INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE cu ON ic.CONSTRAINT_NAME = cu.CONSTRAINT_NAME
WHERE   ic.CONSTRAINT_TYPE = 'FOREIGN KEY'

CREATE TABLE #temp1(    
    SchemaName varchar(255),
    TableName varchar(255),
    ColumnName varchar(255),
    ForeignKeyName sysname
)

OPEN FKColumns_cursor  
FETCH NEXT FROM FKColumns_cursor INTO @SchemaName,@TableName, @ColumnName, @ForeignKeyName

WHILE @@FETCH_STATUS = 0  
BEGIN

    IF ( SELECT COUNT(*)
    FROM        sysobjects o    
        INNER JOIN sysindexes x ON x.id = o.id
        INNER JOIN  syscolumns c ON o.id = c.id 
        INNER JOIN sysindexkeys xk ON c.colid = xk.colid AND o.id = xk.id AND x.indid = xk.indid
    WHERE       o.type in ('U')
        AND xk.keyno <= x.keycnt
        AND permissions(o.id, c.name) <> 0
        AND (x.status&32) = 0
        AND o.name = @TableName
        AND c.name = @ColumnName
    ) = 0
    BEGIN
        INSERT INTO #temp1 SELECT @SchemaName, @TableName, @ColumnName, @ForeignKeyName
    END


    FETCH NEXT FROM FKColumns_cursor INTO @SchemaName,@TableName, @ColumnName, @ForeignKeyName
END  
CLOSE FKColumns_cursor  
DEALLOCATE FKColumns_cursor 

SELECT 'CREATE INDEX IDX_' + ForeignKeyName + ' ON ' + SchemaName + '.' + TableName + '(' + ColumnName +')'
FROM #temp1 
ORDER BY TableName

drop table #temp1 

في منصبي <لأ href = "http://geekswithblogs.net/mnf/archive/2011/06/05/sql-script-to-create-indexes-for-foreign-keys.aspx" يختلط = " نوفولو ">" سكريبت SQL لإنشاء فهارس لمفاتيح الأجنبية " لقد وضع روابط ل2 تطبيقات: <لأ href =" http://sqlblog.com/blogs/paul_nielsen/archive/2007/02/08 /codegen-to-create-indexes-for-fks.aspx "يختلط =" نوفولو "> paul_nielsen الصورة و <لأ href =" http://www.sqlservercentral.com/scripts/Index+Management/ 62069 / "يختلط =" نوفولو "> (مطلوب تسجيل الدخول إلى sqlservercentral ) tklimczak ل

أولا: قائمة الأعمدة مع قيد مفتاح خارجي. وهذا سوف يساعد:

سؤال للحصول على كل قيود المفاتيح الخارجية في SQL الخادم 2000

وعبر مقارنة مع sysindexes وsyscolumns الجداول؛ مجال keys في sysindexes لديه قائمة جميع المفاتيح في المؤشر.

ملحوظة: هذا هو ل SQL Server 2005+ لكن هذا هو السؤال الوحيد الذي وجدت حول هذا الموضوع

.
--Finds foreign keys without indexes
--How to interpret:
--When we delete frpm PkTable, it checks FkColumn for the PkId we are deleting.
--So if FkTable doesn't have an index on FkColumn, then we cannot delete a row from PkTable because it is too slow.
SELECT  rt.name as PkTableName, rc.name as PkColumnName,
fk.name FkName, t.name as FkTableName, c.name as FkColumnName, ddps.row_count, i.name as IndexName
FROM    sys.foreign_key_columns fkc
inner join sys.foreign_keys fk on fkc.constraint_object_id = fk.object_id
inner join sys.tables t on fkc.parent_object_id = t.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 rt on fkc.referenced_object_id = rt.object_id
inner join sys.columns rc on fkc.referenced_object_id = rc.object_id and fkc.referenced_column_id = rc.column_id
inner join sys.indexes ri on t.object_id = ri.object_id
inner JOIN sys.dm_db_partition_stats AS ddps ON ri.OBJECT_ID = ddps.OBJECT_ID AND ri.index_id = ddps.index_id 
left join sys.index_columns ic on ic.object_id = t.object_id and ic.column_id = c.column_id
left join sys.indexes i on ic.object_id = i.object_id and i.index_id = ic.index_id
where ri.index_id < 2 and i.index_id is null and ddps.row_count > 0
order by 
--PkTableName,
ddps.row_count desc
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top