我被分配去查看是否使用了数据库中的所有当前表,以及是否不删除它们。这些是我到目前为止已采取的步骤:
在使用该数据库的程序中搜索表名,以查看是否已基于这些表名在程序中进行了查询。
研究是否在其他任何地方(例如视图或表)使用了表主键(与其他使用的表的连接性)。我用过:
SELECT
t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM
sys.tables AS t
INNER JOIN
sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE
c.name LIKE 'DeflectionId' -- write the column you search here
ORDER BY
schema_name, table_name;
在所有存储过程文本中进行搜索,以查看其中是否使用了表名:
SELECT DISTINCT
o.name AS Object_Name,
o.type_desc
FROM
sys.sql_modules m
INNER JOIN
sys.objects o ON m.object_id = o.object_id
WHERE
m.definition LIKE '%\[Test_Results_LU\]%' ESCAPE '\';
或
SELECT name
FROM sys.procedures
WHERE Object_definition(object_id) LIKE '%Test_Results_LU%'
使用对象资源管理器视图查看数据库中是否存在具有相似/相同名称和大小的表。
您认为我还有其他方法可以用来对其进行更好的调查吗?
这些步骤有效吗?你会怎么做?
答案 0 :(得分:3)
所有这些都是合理的检查对象。要做的另一件事是根据您的SQL Server版本打开概要分析或审核,并实际上监视在合理时间段内使用的表。您可能无法使用生产系统来做到这一点,而且仍然无法100%保证-如果有一个重要的表每年只查询一次,该怎么办?
https://dba.stackexchange.com/questions/40960/logging-queries-and-other-t-sql https://docs.microsoft.com/en-us/sql/relational-databases/security/auditing/view-a-sql-server-audit-log?view=sql-server-2017
删除表之前的另一个建议是显式删除对它们的访问(使用DENY / REVOKE或将它们重命名为table-name_purge)一两个星期,看看是否有人抱怨。如果没有,那么备份并丢弃它们可能是安全的。
答案 1 :(得分:2)
另外两个地方需要检查。这些都依赖于
因此,从这些结果中得出的不存在并不表示该表未被使用,但是您可能会发现有证据表明该表确实在使用中。
SELECT [Schema] = OBJECT_SCHEMA_NAME(object_id),
[ObjectName] = OBJECT_NAME(object_id),
*
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID()
在计划缓存中
USE YourDB
DROP TABLE IF EXISTS #cached_plans, #plans, #results
DECLARE @dbname nvarchar(300) = QUOTENAME(DB_NAME());
SELECT dm_exec_query_stats.creation_time,
dm_exec_query_stats.last_execution_time,
dm_exec_query_stats.execution_count,
dm_exec_query_stats.sql_handle,
dm_exec_query_stats.plan_handle
INTO #cached_plans
FROM sys.dm_exec_query_stats;
WITH distinctph
AS (SELECT DISTINCT plan_handle
FROM #cached_plans)
SELECT query_plan,
plan_handle
INTO #plans
FROM distinctph
CROSS APPLY sys.dm_exec_query_plan(plan_handle);
WITH XMLNAMESPACES (DEFAULT 'http://schemas.microsoft.com/sqlserver/2004/07/showplan')
SELECT cp.*,
st.text,
[Database] = n.value('@Database', 'nvarchar(300)'),
[Schema] = n.value('@Schema', 'nvarchar(300)'),
[Table] = n.value('@Table', 'nvarchar(300)')
INTO #results
FROM #cached_plans cp
JOIN #plans p
ON cp.plan_handle = p.plan_handle
CROSS APPLY sys.dm_exec_sql_text(sql_handle) st
CROSS APPLY query_plan.nodes('//Object[@Database = sql:variable("@dbname") and @Schema != "[sys]"]') qn(n);
SELECT *
FROM #results