Jos*_*osh 5 performance foreign-key database-design sql-server
我的数据库有大约 90 个表。大多数表都有一个UpdatedBy 和AddedBy 列,它们的外键指向用户表。即使在整个数据库中散布适量的数据,这也会导致在清除旧用户记录时的删除过程非常缓慢。
我们的删除查询首先更新当前用户的所有更新/添加引用,然后删除用户记录。由于外键,执行计划显示每个相关表的表扫描。请参阅这篇文章作为我们面临的一个例子。
除了用于分析应用程序问题之外,返回添加和更新的指针并没有真正有用。它们很少使用,并且在它们使用时不是良好信息的主要来源。我想知道是否应该一起删除外键约束,或者是否应该将更新审计转移到一个单独的表中,该表保留表名、列、值和用户 ID 的记录,或者是否还有其他一些DBA 社区在这种情况下倾向于采用的普遍接受的方法。
dru*_*zin 10
确保受约束的列上有索引,因为 dbms 将使用引用表中的这些列进行查找。
您可以尝试使用此脚本,它会为级联约束引用的任何非索引列生成索引创建脚本。
SELECT 'CREATE NONCLUSTERED INDEX IX_'+OBJECT_NAME(fk.parent_object_id)+'_'+c.name+' ON '+OBJECT_NAME(fk.parent_object_id)+'('+c.name+') WITH (ONLINE=ON)'
--, OBJECT_NAME(fk.referenced_object_id) AS referenced_tale, cc.name
FROM
sys.foreign_keys fk
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.columns cc ON fkc.referenced_object_id = cc.object_id AND fkc.referenced_column_id = cc.column_id
WHERE delete_referential_action_desc IN ('CASCADE', 'SET_NULL')
AND NOT EXISTS
(
SELECT 1
FROM
SYS.index_columns ic
INNER JOIN sys.indexes i ON i.object_id = ic.object_id AND ic.index_id = i.index_id
WHERE
1 = 1
AND type_DESC IN ('CLUSTERED','NONCLUSTERED')
AND ic.OBJECT_ID = c.object_id
AND ic.column_id = c.column_id
AND ic.is_included_column = 0
)
Run Code Online (Sandbox Code Playgroud)