Labels

admin (1) aix (1) alert (1) always-on (2) Architecture (1) aws (3) Azure (1) backup (3) BI-DWH (10) Binary (3) Boolean (1) C# (1) cache (1) casting (3) cdc (1) certificate (1) checks (1) cloud (3) cluster (1) cmd (7) collation (1) columns (1) compilation (1) configurations (7) Connection-String (2) connections (6) constraint (6) copypaste (2) cpu (2) csv (3) CTE (1) data-types (1) datetime (23) db (547) DB2 (1) deadlock (2) Denali (7) device (6) dotNet (5) dynamicSQL (11) email (5) encoding (1) encryption (4) errors (124) excel (1) ExecutionPlan (10) extended events (1) files (7) FIPS (1) foreign key (1) fragmentation (1) functions (1) GCP (2) gMSA (2) google (2) HADR (1) hashing (3) in-memory (1) index (3) indexedViews (2) insert (3) install (10) IO (1) isql (6) javascript (1) jobs (11) join (2) LDAP (2) LinkedServers (8) Linux (15) log (6) login (1) maintenance (3) mariadb (1) memory (4) merge (3) monitoring (4) MSA (2) mssql (444) mssql2005 (5) mssql2008R2 (20) mssql2012 (2) mysql (36) MySQL Shell (5) network (1) NoSQL (1) null (2) numeric (9) object-oriented (1) offline (1) openssl (1) Operating System (4) oracle (7) ORDBMS (1) ordering (2) Outer Apply (1) Outlook (1) page (1) parameters (2) partition (1) password (1) Performance (103) permissions (10) pivot (3) PLE (1) port (4) PostgreSQL (14) profiler (1) RDS (3) read (1) Replication (12) restore (4) root (1) RPO (1) RTO (1) SAP ASE (48) SAP RS (20) SCC (4) scema (1) script (8) security (10) segment (1) server (1) service broker (2) services (4) settings (75) SQL (74) SSAS (1) SSIS (19) SSL (8) SSMS (4) SSRS (6) storage (1) String (35) sybase (57) telnet (2) tempdb (1) Theory (2) tips (120) tools (3) training (1) transaction (6) trigger (2) Tuple (2) TVP (1) unix (8) users (3) vb.net (4) versioning (1) windows (14) xml (10) XSD (1) zip (1)

Finding unused DB objects (Tables, Views, Procs, Functions)

Check by dependencies:

Figure out which objects have no internal dependencies:
select distinct so.id, so.name, so.Type
from sys.sysdepends sd
inner join sys.sysobjects so on so.id = sd.id
-- next line: filter by schema' if required:
inner join sys.objects o on o.object_id = so.id  and SCHEMA_NAME(o.schema_id) <> 'dbo'
where 
    not exists ( select 1 from sysdepends sd2
where sd2.depid = so.id )
and so.Type in ('AF', 'FN', 'FS', 'FT', 'IF', 'TF', 'S', 'U', 'V') -- depend which types we want to check (and if we want)

I did another checks:
1. Insert the result of this quert into table 
2. Search calls to those objects in field ROUTINE_DEFINITION in table INFORMATION_SCHEMA.ROUTINES. remove the objects that I found here.
3. Additional check in syscomments.

-- step 1
declare @UnUsedObjects TABLE (o_id int, o_name sysname, o_type char(2))

insert into @UnUsedObjects (o_id, o_name, o_type)

select distinct so.id, so.name, so.Type
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 )
and so.Type in ('AF', 'FN', 'FS', 'FT', 'IF', 'TF', 'S', 'U', 'V')
-- end of insert

select * from @UnUsedObjects --check after step 1

-- step 2
DECLARE @o_name nvarchar(50), @o_nameLike nvarchar(50)
DECLARE CursorWO CURSOR FORWARD_ONLY  FOR 
-------------- Start Select --------------------------
select cast(o_name as nvarchar(50)), cast('%' + o_name + '%' as nvarchar(50))
from @UnUsedObjects
-------------- End Select ----------------------------
OPEN CursorWO
FETCH NEXT FROM CursorWO 
INTO @o_name, @o_nameLike
WHILE (@@FETCH_STATUS = 0)
BEGIN
if exists (SELECT * FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_DEFINITION LIKE @o_nameLike
and SPECIFIC_NAME <> @o_name
) delete from @UnUsedObjects where o_name = @o_name
--Get next record from cursor
FETCH NEXT FROM CursorWO 
INTO @o_name, @o_nameLike
END
CLOSE CursorWO
DEALLOCATE CursorWO

select *, (CASE WHEN o_type IN ('S', 'U') THEN 10
WHEN o_type IN ('AF', 'FN', 'FS', 'FT', 'IF', 'TF') THEN 20
WHEN o_type IN ('V') THEN 30
ELSE 40
END) as ord
from @UnUsedObjects
order by ord, o_type

-- step 3
-- run this for each object:
select object_name(id) as object_name_, count(*) as count_ 
from syscomments where text like '%XXXXX%' 
group by object_name(id) order by object_name(id)

More check:
select r.routine_name, r.routine_type, o.Type, o.name as objectName
from sys.objects o
left join INFORMATION_SCHEMA.ROUTINES r on r.ROUTINE_DEFINITION LIKE '%' + o.name + '%'
             and SPECIFIC_SCHEMA <> 'dbo'  -- schema check, if required
where o.Type in ('S', 'U')
and r.routine_name is null


EXEC sp_depends @objname = N'TABLENAME'



Check by DB actual execution:
-- get last execution time:
SELECT object_name(m.object_id), MAX(qs.last_execution_time)
FROM sys.sql_modules m
LEFT JOIN (sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text (qs.sql_handle) st)
ON m.object_id = st.objectid
AND st.dbid = db_id()
GROUP BY object_name(m.object_id)
order by MAX(qs.last_execution_time) desc

-- get accesses count of tables:
SELECT t.name AS 'Table', 
SUM(i.user_seeks + i.user_scans + i.user_lookups) AS 'Total accesses',
SUM(i.user_seeks) AS 'Seeks',
SUM(i.user_scans) AS 'Scans',
SUM(i.user_lookups) AS 'Lookups'
FROM sys.dm_db_index_usage_stats i 
RIGHT OUTER JOIN sys.tables t ON (t.object_id = i.object_id)
GROUP BY i.object_id, t.name
ORDER BY [Total accesses] desc 


Links:


Listing SQL Server Object Dependencies:

No comments:

Post a Comment