Showing posts with label unused. Show all posts
Showing posts with label unused. Show all posts

Sunday, February 19, 2012

Identifying Unused Tables

I have inherited support for a database with many used tables. There
isn't any documentation on what is used or dead. I was hoping to run
traces and capture the objectid but the property doesn't work that
way.

Any good ideas would be appreciated.david_0 (dosberg@.yahoo.com) writes:
> I have inherited support for a database with many used tables. There
> isn't any documentation on what is used or dead. I was hoping to run
> traces and capture the objectid but the property doesn't work that
> way.

If the application uses only stored procedures, then it is fairly easy:
you search the code for all tables, and the keep track of which tables
does not give a hit. Alright, so that opens the question if there are
stored procedures which are not used.

If the application sends SELECT statement from the code, your best bet
is probably to search the application code, again once for each table.
If you find no references for a table you may want to make extra
precautions as it could be a lookup table that is being reference in
a foreign-ley constraint or trigger only. Or it may be part of a view
that is not in use.

Using the Profiler and the search the output is a possibility, but there
may be tables which are used in end-of-the-year functions only.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp|||Here is what I came up with that will work for my situation. With a
little rework it could be used in other cases.

It doesn't do anything to detect inline sql on the client side. That
issue doesn't really apply in my situation.

DECLARE @.tbl TABLE(id INT IDENTITY(1,1), tblname VARCHAR(128),
found_flag CHAR(1))
DECLARE @.cnt int
DECLARE @.loop int
DECLARE @.parm varchar(255)

/*
*load variable with tables that aren't in sysdepends
*/
INSERT INTO @.tbl (tblname, found_flag)
SELECT
OBJECT_NAME(a.id),'N'
FROM
sysobjects a LEFT JOIN sysdepends b ON a.id=depid
WHERE
a.type='u' AND b.depid IS NULL
ORDER BY object_name(a.id)

/*
*setup variables for the loop
*/
SELECT @.cnt=MAX(id) FROM @.tbl
SET @.loop=1

/*
*take list of tables with no dependencies and look for job steps
that might reference them.
*/
WHILE @.loop <=@.cnt BEGIN

SELECT @.parm=tblname FROM @.tbl WHERE id=@.loop

IF EXISTS (SELECT job_id FROM msdb..sysjobsteps WHERE
CHARINDEX(@.parm,command)>0)
BEGIN
UPDATE @.tbl SET found_flag='Y' where id=@.loop
END
SET @.loop=@.loop+1
END

/*
*return table names not used in job steps or having object
dependencies
*/
SELECT tblname FROM @.tbl WHERE found_flag='N'

Erland Sommarskog <esquel@.sommarskog.se> wrote in message news:<Xns9536EBF5675DYazorman@.127.0.0.1>...
> david_0 (dosberg@.yahoo.com) writes:
> > I have inherited support for a database with many used tables. There
> > isn't any documentation on what is used or dead. I was hoping to run
> > traces and capture the objectid but the property doesn't work that
> > way.
> If the application uses only stored procedures, then it is fairly easy:
> you search the code for all tables, and the keep track of which tables
> does not give a hit. Alright, so that opens the question if there are
> stored procedures which are not used.
> If the application sends SELECT statement from the code, your best bet
> is probably to search the application code, again once for each table.
> If you find no references for a table you may want to make extra
> precautions as it could be a lookup table that is being reference in
> a foreign-ley constraint or trigger only. Or it may be part of a view
> that is not in use.
> Using the Profiler and the search the output is a possibility, but there
> may be tables which are used in end-of-the-year functions only.|||david_0 (dosberg@.yahoo.com) writes:
> Here is what I came up with that will work for my situation. With a
> little rework it could be used in other cases.
>...
> INSERT INTO @.tbl (tblname, found_flag)
> SELECT
> OBJECT_NAME(a.id),'N'
> FROM
> sysobjects a LEFT JOIN sysdepends b ON a.id=depid
> WHERE
> a.type='u' AND b.depid IS NULL
> ORDER BY object_name(a.id)

Note however that sysdepends is at best approxamite. For instance if you
drop and recreate a table, you lose all entries in sysdepends for
the reference, so the table may appear unreferenced.

--
Erland Sommarskog, SQL Server MVP, esquel@.sommarskog.se

Books Online for SQL Server SP3 at
http://www.microsoft.com/sql/techin.../2000/books.asp

Identifying unused columns in multiple databases

Hi - we have a situation where we have 23 identical databases on
servers across the country. We know that there are fields within this
db that no one is using and would like to be able to identify all of
them so they can be removed across the board. (There are multiple
tables and columns) We would of course have to verify that none of the
23 offices are using a particular field before it's removed as the db's
need to stay identical. (data in each db varies).
Anyway - I came across this posting which sounds like what we're
looking for, but it specifically references varchar and nvarchar fields
- I can't figure out what to modify in it to make this work for any
type of field. Can anyone point me in the right direction?
This is the posting:
> How can I find all the varchar columns in a table?

> I'm looking for an existing empty or null column rather than add a column.
This will generate a script for the current database that will tell you
all
of the varchar or nvarchar columns, and what percentage of them are
"unused" -- either NULL or empty strings.
SELECT 'SELECT '''+TABLE_NAME+''','''+COLUMN_NAME+''','
''
+DATA_TYPE+'('+RTRIM(CHARACTER_MAXIMUM_L
ENGTH)
+')'',''empty'',COUNT(*) FROM '+TABLE_SCHEMA+'.'+TABLE_NAME
+' WITH (NOLOCK) WHERE
LTRIM(RTRIM(COALESCE('+COLUMN_NAME+','''
')))=''''
UNION
SELECT '''+TABLE_NAME+''','''+COLUMN_NAME+''','
''
+DATA_TYPE+'('+RTRIM(CHARACTER_MAXIMUM_L
ENGTH)
+')'',''total'',COUNT(*) FROM '+TABLE_SCHEMA+'.'+TABLE_NAME
+' WITH (NOLOCK)'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE LIKE '%varchar'
You can run this in Query Analyzer, and it will generate a script in
the
bottom pane. Copy to a new query window and let 'er rip. Should take
a
while on larger databases. I use WITH (NOLOCK) for this kind of task
to
avoid concurrency and blocking issues; if you need an
up-to-the-millisecond
guaranteed read on the whole table, you may opt to leave that out (but
I do
not recommend it on a production server).
Thank you in advance.Please do not take offense, but if are not familiar enough with SQL Server
and SQL in general to make the necessary change to this query, then you
really are not qualified to be working on the changes you are talking about.
I am not trying to be mean, but your question is much simpler than the task
you intend to eventually perform. If you need help at this point, you will
get disastrous results later on. It is best to get someone who is more of
an expert in such things to handle this project.
"Debbie" <deborah.young@.mail.va.gov> wrote in message
news:1140104286.351275.153030@.g43g2000cwa.googlegroups.com...
> Hi - we have a situation where we have 23 identical databases on
> servers across the country. We know that there are fields within this
> db that no one is using and would like to be able to identify all of
> them so they can be removed across the board. (There are multiple
> tables and columns) We would of course have to verify that none of the
> 23 offices are using a particular field before it's removed as the db's
> need to stay identical. (data in each db varies).
> Anyway - I came across this posting which sounds like what we're
> looking for, but it specifically references varchar and nvarchar fields
> - I can't figure out what to modify in it to make this work for any
> type of field. Can anyone point me in the right direction?
> This is the posting:
>
column.
>
> This will generate a script for the current database that will tell you
> all
> of the varchar or nvarchar columns, and what percentage of them are
> "unused" -- either NULL or empty strings.
> SELECT 'SELECT '''+TABLE_NAME+''','''+COLUMN_NAME+''','
''
> +DATA_TYPE+'('+RTRIM(CHARACTER_MAXIMUM_L
ENGTH)
> +')'',''empty'',COUNT(*) FROM '+TABLE_SCHEMA+'.'+TABLE_NAME
> +' WITH (NOLOCK) WHERE
> LTRIM(RTRIM(COALESCE('+COLUMN_NAME+','''
')))=''''
> UNION
> SELECT '''+TABLE_NAME+''','''+COLUMN_NAME+''','
''
> +DATA_TYPE+'('+RTRIM(CHARACTER_MAXIMUM_L
ENGTH)
> +')'',''total'',COUNT(*) FROM '+TABLE_SCHEMA+'.'+TABLE_NAME
> +' WITH (NOLOCK)'
> FROM INFORMATION_SCHEMA.COLUMNS
> WHERE DATA_TYPE LIKE '%varchar'
>
> You can run this in Query Analyzer, and it will generate a script in
> the
> bottom pane. Copy to a new query window and let 'er rip. Should take
> a
> while on larger databases. I use WITH (NOLOCK) for this kind of task
> to
> avoid concurrency and blocking issues; if you need an
> up-to-the-millisecond
> guaranteed read on the whole table, you may opt to leave that out (but
> I do
> not recommend it on a production server).
>
> Thank you in advance.
>|||By "using the column", do you mean:
#1 if the column is populated with at least some data
#2 if there are any queries or procedures that actually reference the
column
The programming below seems to be querying for any columns that are all NULL
or zero length.
Also, a column may have been populated at some point in the past, but is
currently obsolete and not used. If you really need to audit which tables /
columns are in use by the application during normal usage, then you can
setup an object trace in SQL Server Profiler and let it run the background
for a complete business cycle.
http://msdn.microsoft.com/library/d...
ethowto15.asp
"Debbie" <deborah.young@.mail.va.gov> wrote in message
news:1140104286.351275.153030@.g43g2000cwa.googlegroups.com...
> Hi - we have a situation where we have 23 identical databases on
> servers across the country. We know that there are fields within this
> db that no one is using and would like to be able to identify all of
> them so they can be removed across the board. (There are multiple
> tables and columns) We would of course have to verify that none of the
> 23 offices are using a particular field before it's removed as the db's
> need to stay identical. (data in each db varies).
> Anyway - I came across this posting which sounds like what we're
> looking for, but it specifically references varchar and nvarchar fields
> - I can't figure out what to modify in it to make this work for any
> type of field. Can anyone point me in the right direction?
> This is the posting:
>
>
> This will generate a script for the current database that will tell you
> all
> of the varchar or nvarchar columns, and what percentage of them are
> "unused" -- either NULL or empty strings.
> SELECT 'SELECT '''+TABLE_NAME+''','''+COLUMN_NAME+''','
''
> +DATA_TYPE+'('+RTRIM(CHARACTER_MAXIMUM_L
ENGTH)
> +')'',''empty'',COUNT(*) FROM '+TABLE_SCHEMA+'.'+TABLE_NAME
> +' WITH (NOLOCK) WHERE
> LTRIM(RTRIM(COALESCE('+COLUMN_NAME+','''
')))=''''
> UNION
> SELECT '''+TABLE_NAME+''','''+COLUMN_NAME+''','
''
> +DATA_TYPE+'('+RTRIM(CHARACTER_MAXIMUM_L
ENGTH)
> +')'',''total'',COUNT(*) FROM '+TABLE_SCHEMA+'.'+TABLE_NAME
> +' WITH (NOLOCK)'
> FROM INFORMATION_SCHEMA.COLUMNS
> WHERE DATA_TYPE LIKE '%varchar'
>
> You can run this in Query Analyzer, and it will generate a script in
> the
> bottom pane. Copy to a new query window and let 'er rip. Should take
> a
> while on larger databases. I use WITH (NOLOCK) for this kind of task
> to
> avoid concurrency and blocking issues; if you need an
> up-to-the-millisecond
> guaranteed read on the whole table, you may opt to leave that out (but
> I do
> not recommend it on a production server).
>
> Thank you in advance.
>|||I'd suggest running the trace (after it has been tuned to only trace relevan
t
events and return relevant data) for a month (or whatever the actual
turn-over time is).
After that you need to analyze the trace data, identifying individual unused
objects.
The following activities should not be done in live production.
Unused objects should first be renamed before actually being dropped -
rename one at a time to get a clear picture of their actual usage.
After the system has been running successfully for your specific turn-over
time with the renamed objects, you could consider dropping them - in a test
environment first, of course.
This is the bottom-to-top approach.
There is, however, another approach to this - analyze your actual business
requirements. If you think you have unused columns, maybe the entire data
model is wrong for you, and needs to be redesigned. This approach may even
yield better results.
ML
http://milambda.blogspot.com/