1- use [your db name here];
2-
1+ /*
2+ Created: 2019-03-12 by Michael J. Swart
3+ Modified: 2019-03-19 by Konstantin Taranov
4+ Original Link: http://michaeljswart.com/2019/03/lonely-tables-in-sql-server/
5+ Source link: https://github.com/ktaranov/sqlserver-kit/blob/master/Scripts/Find_Not_Used_Legacy_Tables.sql
6+ */
7+
8+ /* USE [your db name here]; */
9+
10+
11+ IF OBJECT_ID(N' tempdb..#myplans' , ' U' ) IS NOT NULL DROP TABLE # myplans;
12+ IF OBJECT_ID(N' tempdb..#myExecutions' , ' U' ) IS NOT NULL DROP TABLE # myExecutions;
13+
314SELECT qs .query_hash ,
415 qs .plan_handle ,
5- cast(null as xml) as query_plan
16+ cast(null AS xml) AS query_plan
617 INTO # myplans
718 FROM sys .dm_exec_query_stats qs
819 CROSS APPLY sys .dm_exec_plan_attributes (qs .plan_handle ) pa
920 WHERE pa .attribute = ' dbid'
10- AND pa .value = db_id ();
21+ AND pa .value = DB_ID ();
1122
12- WITH duplicate_queries AS
13- (
14- SELECT ROW_NUMBER() OVER (PARTITION BY query_hash ORDER BY (SELECT 1 )) n
23+ WITH duplicate_queries AS (
24+ SELECT ROW_NUMBER() OVER (PARTITION BY query_hash ORDER BY (SELECT 1 )) AS n
1525 FROM # myplans
1626)
1727DELETE duplicate_queries
1828 WHERE n > 1 ;
19-
29+
2030UPDATE # myplans
2131 SET query_plan = qp .query_plan
22- FROM # myplans mp
23- CROSS APPLY sys .dm_exec_query_plan (mp .plan_handle ) qp;
24-
32+ FROM # myplans AS mp
33+ CROSS APPLY sys .dm_exec_query_plan (mp .plan_handle ) AS qp;
34+
2535WITH XMLNAMESPACES (DEFAULT ' http://schemas.microsoft.com/sqlserver/2004/07/showplan' ),
26- my_cte AS
27- (
36+ my_cte AS (
2837 SELECT q .query_hash ,
2938 obj .value (' (@Schema)[1]' , ' sysname' ) AS [schema_name],
3039 obj .value (' (@Table)[1]' , ' sysname' ) AS table_name
@@ -36,27 +45,27 @@ SELECT query_hash, [schema_name], table_name
3645 INTO # myExecutions
3746 FROM my_cte
3847 WHERE [schema_name] IS NOT NULL
39- AND OBJECT_ID([schema_name] + ' .' + table_name) IN (SELECT object_id FROM sys .tables )
48+ AND OBJECT_ID([schema_name] + ' .' + table_name) IN (SELECT [ object_id] FROM sys .tables )
4049 GROUP BY query_hash, [schema_name], table_name;
41-
42- WITH multi_table_queries AS
43- (
50+
51+ WITH multi_table_queries AS (
4452 SELECT query_hash
4553 FROM # myExecutions
4654 GROUP BY query_hash
4755 HAVING COUNT (* ) > 1
4856),
49- lonely_tables as
50- (
57+ lonely_tables AS (
5158 SELECT [schema_name], table_name
5259 FROM # myExecutions
5360 EXCEPT
5461 SELECT [schema_name], table_name
55- FROM # myexecutions WHERE query_hash IN (SELECT query_hash FROM multi_table_queries)
62+ FROM # myExecutions WHERE query_hash IN (SELECT query_hash FROM multi_table_queries)
5663)
57- SELECT l.* , ps .row_count
58- FROM lonely_tables l
59- JOIN sys .dm_db_partition_stats ps
64+ SELECT l.[schema_name]
65+ , l .table_name
66+ , ps .row_count
67+ FROM lonely_tables AS l
68+ LEFT JOIN sys .dm_db_partition_stats AS ps
6069 ON OBJECT_ID(l.[schema_name] + ' .' + l .table_name ) = ps .object_id
61- WHERE ps .index_id in (0 ,1 )
70+ WHERE ps .index_id in (0 , 1 )
6271 ORDER BY ps .row_count DESC ;
0 commit comments