Очистка базы данных MSSQL - как найти неиспользуемые объекты (таблицы, представления, процессы, функции)

предположим, вы унаследовали базу данных MS SQL 2000 или 2005, и вы знаете, что некоторые из таблиц, представлений, процессов и функций фактически не используются в конечном продукте.

есть ли какой-то внутренний журнал или другой механизм, который мог бы сказать мне, какие объекты не вызываются? или были вызваны только несколько раз против тысяч раз.

3 ответов


Это так вопрос,определение неиспользуемых объектов в Microsoft SQL Server 2005, может быть актуальным.


ответ будет немного зависеть от того, как была собрана база данных, но мой подход к подобной проблеме был 3-кратным:

выясните, какие объекты не имеют внутренних зависимостей. Вы можете решить это из запросов к sysdepends, таких как:

select 
    id, 
    name
from
    sys.sysdepends sd
inner join sys.sysobjects so
    on so.id = sd.id
where 
    not exists (
        select 
            1
        from 
            sysdepends sd2
        where 
            sd2.depid = so.id
    )

вы должны объединить это со сбором типа объекта (sysobjects.xtype), поскольку вы хотите изолировать только таблицы, функции, сохраненные процессы и представления. Также игнорируйте любые процедуры запуска " sp_", если только люди не создавали процедуры с этими именами для вашего приложения!

многие из возвращенных процедур могут быть точками входа вашего приложения. То есть процедуры, которые вызываются из вашего уровня приложения или из какого-либо другого удаленного вызова и не имеют объектов, зависящих от них в базе данных.

предполагая, что процесс не будет слишком инвазивным (он создаст некоторую дополнительную нагрузку, хотя и не слишком много), теперь вы можете включить некоторые профилирование событий SP:Starting, SQL:BatchStarting и / или SP:StmtStarting. Запустите это до тех пор, пока вы считаете нужным, идеально войдя в таблицу sql для легкой перекрестной ссылки. Вы должны быть в состоянии устранить многие из процедур, которые вызываются непосредственно из приложения.

путем перекрестной ссылки на текстовые данные из этого журнала и списка зависимых объектов вы, надеюсь, изолировали большинство неиспользуемых процедур.

наконец, вы можете взять ваш список кандидатов в результате этого процесса и grep вашей базы исходного кода против них. Это громоздкая задача, и то, что вы находите ссылки в своем коде, не означает, что они вам нужны! Возможно, просто код не был удален, хотя теперь он логически недоступен.

Это далеко не идеальный процесс. Относительно чистой альтернативой является настройка гораздо более подробного (и, следовательно, инвазивного) профилирования на сервере для мониторинга всей активности. Это может включать в себя все Инструкция SQL вызывается во время работы журнала. Затем вы можете работать с зависимыми таблицами или даже с зависимостями между базами данных из этих текстовых данных. Я обнаружил надежность деталей журнала (слишком много строк в секунду, пытающихся быть проанализированными) и явную количественность данных, с которыми трудно иметь дело. Если ваше приложение с меньшей вероятностью пострадает от этого, это может быть хороший подход.

предостережение:

потому что, насколько я знаю, нет идеального ответ на это будьте особенно осторожны с удалением таблиц. Процедуры, функции и представления легко заменяются, если что-то идет не так (хотя убедитесь, что они есть в системе управления версиями, прежде чем сжигать их, конечно!). Если вы действительно нервничаете, почему бы не переименовать таблицу и не создать представление со старым именем, у вас есть легкий выход.


мы также можем найти неиспользуемые столбцы и таблицы, используя следующий запрос. Я устал писать курсором. Курсор даст вам информацию о каждом столбце n каждой таблицы.

declare @name varchar(200), @id bigint, @columnname varchar(500)
declare @temptable table
(
 table_name varchar(500),
 Status bit
)
declare @temp_column_name table 
(
 table_name varchar(500),
 column_name varchar(500),
 Status bit
)


declare find_table_dependency cursor for
select name, id from sysobjects where xtype ='U'
open find_table_dependency
fetch find_table_dependency into @name, @id
while @@fetch_Status = 0
begin

 if exists(select top 1 name from sysobjects where id in 
   (select id from syscomments where text like '%'+@name +'%'))
  insert into @temptable
  select @name, 1
 else 
  insert into @temptable
  select @name, 0

 declare find_column_dependency cursor for
    select name from syscolumns where id = @id
 open find_column_dependency
 fetch find_column_dependency into @columnname
 while @@fetch_Status = 0
 begin

  if exists(select top 1 name from sysobjects where id in 
   (select id from syscomments where text like '%'+@columnname +'%'))
   insert into @temp_column_name
   select @name,@columnname, 1
  else 
   insert into @temp_column_name
   select @name,@columnname, 0

  fetch find_column_dependency into @columnname
 end
 close find_column_dependency
 deallocate find_column_dependency


 fetch find_table_dependency into @name, @id
end
close find_table_dependency
deallocate find_table_dependency

select * from @temptable
select * from @temp_column_name