Query to get tables having indexing in a particular database - sql

Can anyone provide me the query in sql server to extract the tables that have been done indexing, for a particular database....

Your question is somewhat unclear. This will return all tables with at least one index.
select DISTINCT OBJECT_NAME(object_id)
from sys.indexes
where type<>0
Or for SQL Server 2000
select DISTINCT OBJECT_NAME(id)
from sysindexes
where indid<>0

select object_name(object_id),* from sys.indexes where type <> 0
This will return you all the indexes available in your database. But beware, it also lists the system tables.

The sys.indexes DMV should have what you're looking for:
SELECT TableName = object_name(Object_Id)
, IndexName = Name
, IndexType = Type_Desc
FROM sys.indexes
The Type_Desc column will tell you whether you're looking at a heap, a clustered index, or a non-clustered index.
Joining to sys.tables will limit the results to user tables and leave out system tables:
SELECT TableName = st.Name
, IndexName = si.name
, IndexType = si.type_desc
FROM SYS.indexes si
JOIN SYS.tables st
ON si.object_id = st.object_id

Related

DMVs to get index configuration information

I want to check whether all the tables in my Database has clusterd index on which type of column(eg:int) and whether the clustered index is on a single/multipe columns. I was not able to figure out which DMvs or Views to retreive this information. Please help.
below sql will give you list of the clusterd indexes and table name with few more detail. you can modified this to get to you results.
SELECT 'ClusteredIndexName' = SI.Name,
'TableName' = SO.Name,
'ColumCount' = IK.IndexColumnCount,
'IsUnique' = CASE WHEN SI.is_unique = 0 THEN 'N' ELSE 'Y' END
,SI.type_desc
FROM SYS.INDEXES SI
JOIN SYS.OBJECTS SO -- Joining on SYS.OBJECTS to get the TableName
ON SO.OBJECT_ID = SI.Object_ID
JOIN ( -- Joining on a Derived view to work out how many columns exist on the clustered index
SELECT 'IndexColumnCount' = MAX(KEY_ORDINAL), OBJECT_ID, index_id
FROM SYS.INDEX_COLUMNS
GROUP BY OBJECT_ID, index_id
) AS IK
ON IK.object_id = SI.Object_ID
AND IK.index_id = SI.index_id
WHERE SI.type_desc = 'CLUSTERED' and
SI.OBJECT_ID NOT IN (SELECT OBJECT_ID
FROM SYS.ALL_OBJECTS
WHERE TYPE = 'S') -- Not system tables
AND SO.Type = 'U'
AND SO.is_ms_shipped = 0
Sql Server Management Studio lets you see the definition of all indexes on a table. Find the table in the Tables folder, expand, and expand Indexes. Select Properties on a particular index to view columns and other properties.
SELECT * FROM sys.indexes (I think, its been a while since I used SQL Server).

SQL grouping results

I'm trying to get the last time a table was updated by the users:
Declare #Collect Table (Name Varchar(100),last_user_update datetime)
Insert into #Collect
EXEC sp_MSForEachTable 'SELECT ''?'' as TableName,
last_user_update
FROM sys.dm_db_index_usage_stats
WHERE database_id = DB_ID(''SP3D_DB_RESEARCH_MDB'') AND OBJECT_ID = OBJECT_ID(''?'')'
SELECT * FROM #Collect ORDER BY last_user_update DESC
The problem is that in the results, some tables are appearing 3 times (please see the image bellow)
Since it appears that all tables duplicated have the same last updated time. Is there any way to group the results by the table name?
If the values are indeed the same, you can just add DISTINCT to the query, and have it return unique results
SELECT DISTINCT ''?'' as TableName, last_user_update ...
If you want to group after the fact, and only the last update interests you, you can do
SELECT TableName, max(last_user_update) as last_update
FROM #Collect
GROUP BY TableName
ORDER BY 2 DESC
Tables can have multiple indexes. The dynamic management view sys.dm_db_index_usage_stats will have separate entries for each index.
If you want to see the index name for each one, try this:
SELECT
o.name as TableName,
i.name as IndexName,
istats.last_user_update
from sys.dm_db_index_usage_stats istats
inner join sys.objects o
on o.object_id = istats.object_id
inner join sys.indexes i
on i.index_id = istats.index_id
and i.object_id = istats.object_id
order by
o.name,
i.name
Or, if you don't care about that and just want the last update time, you can group by the table name:
SELECT
o.name as TableName,
max(istats.last_user_update)
from sys.dm_db_index_usage_stats istats
inner join sys.objects o
on o.object_id = istats.object_id
group by
o.name
You can do an insert directly into your table with this query:
declare #Collect table (Name varchar(100),last_user_update datetime)
insert into #Collect
select
o.name as TableName,
istats.last_user_update
from sys.dm_db_index_usage_stats istats
inner join sys.objects o
on o.object_id = istats.object_id
inner join sys.indexes i
on i.index_id = istats.index_id
and i.object_id = istats.object_id
where database_id = db_id('SP3D_DB_RESEARCH_MDB')
Also, I'm not sure what your goal is, but please understand that this view only has entries for indexes that have activity on them. If an index is unused, it is not in this view. The first access creates a row in the view. The real interesting stuff on this view is the seek and scan information.
See this note from MSDN:
When an index is used, a row is added to sys.dm_db_index_usage_stats
if a row does not already exist for the index. When the row is added,
its counters are initially set to zero.
If your goal is to enumerate all the indexes and then show the last update date for all of them, you'll need to join to sys.indexes and then left join to sys.dm_db_index_usage_stats.

find all tables not referenced in stored procedures

I have sql server database with numerous tables, some no longer used so I want to remove them. All database interactivity is via stored procedure to these tables.
Is there a database sql script that I can use that will list all tables not referenced in any of the stored procedures in the database?
If SQL Server 2008 then the dependencies information is now reliable.
SELECT SCHEMA_NAME(t.schema_id),
t.name
FROM sys.tables t
WHERE is_ms_shipped = 0
AND NOT EXISTS (SELECT *
FROM sys.sql_expression_dependencies d
WHERE d.referenced_entity_name = t.name
AND (( is_ambiguous = 1 or is_caller_dependent=1)
OR
d.referenced_id = t.object_id) )
You can't do this if you use any dynamic T-SQL. Dynamic T-SQL won't show up in any investigation of object dependencies.
Instead, you can use the DMV sys.dm_db_index_usage_stats to find what objects haven't been referenced by any queries. Here's a query I did on SQLServerPedia for that:
http://sqlserverpedia.com/wiki/Find_Indexes_Not_In_Use
The query is designed for performance tuning indexes, so you'll need to tweak a few lines. Here's the modified query:
SELECT
o.name
, indexname=i.name
, i.index_id
, reads=user_seeks + user_scans + user_lookups
, writes = user_updates
, rows = (SELECT SUM(p.rows) FROM sys.partitions p WHERE p.index_id = s.index_id AND s.object_id = p.object_id)
, CASE
WHEN s.user_updates < 1 THEN 100
ELSE 1.00 * (s.user_seeks + s.user_scans + s.user_lookups) / s.user_updates
END AS reads_per_write
, 'DROP INDEX ' + QUOTENAME(i.name)
+ ' ON ' + QUOTENAME(c.name) + '.' + QUOTENAME(OBJECT_NAME(s.object_id)) as 'drop statement'
FROM sys.dm_db_index_usage_stats s
INNER JOIN sys.indexes i ON i.index_id = s.index_id AND s.object_id = i.object_id
INNER JOIN sys.objects o on s.object_id = o.object_id
INNER JOIN sys.schemas c on o.schema_id = c.schema_id
WHERE OBJECTPROPERTY(s.object_id,'IsUserTable') = 1
AND s.database_id = DB_ID()
ORDER BY reads
Keep in mind that this catches all indexes, and you'll need to sift through - some of your objects may be heaps, some may have clustered indexes, etc. I'll leave this as a wiki so someone more ambitious than me can edit it to build a deduped list. :-D
Check this discussion tsql script to find tables not being used by stored procedures, views, functions, etc?
And this article(listed from above discussion) http://www.mssqltips.com/tip.asp?tip=1294 discusses about SQL object dependencies.
Perhaps something along these lines:
select t.table_name
from INFORMATION_SCHEMA.TABLES t
where not exists (
select 1 from INFORMATION_SCHEMA.ROUTINES r
where object_definition(object_id(r.ROUTINE_NAME)) like '%'+t.TABLE_NAME+'%'
) order by t.TABLE_NAME
The first query lists table with the stored proc name that uses it.
The second query lists table with the number of stored procs using it.
-- list all tables / sprocs
select t.name [Table], p.name [StoredProc]
from sys.tables t
left join sys.procedures p on (OBJECT_DEFINITION(p.object_id)) like '%' + t.name + '%'
where t.type = 'U'
order by t.name, p.name
-- count stored procs using table
select t.name [Table], count(p.name) [Count]
from sys.tables t
left join sys.procedures p on (OBJECT_DEFINITION(p.object_id)) like '%' + t.name + '%'
where t.type = 'U'
group by t.name
order by t.name
Here's one you might try:
select
name
from
sys.tables t
left join
sys.sql_dependencies d
on
t.object_id =
d.referenced_major_id
where
d.referenced_major_id is null
Otherwise, here's a reference I've used in the past:
http://www.mssqltips.com/tip.asp?tip=1294
If performace isnt to much of a problem you could try the following.
Select Distinct Object_Name(ID)
From syscomments
Where ID Not In (Select ID From syscomments Where Text Like '%<TableName>%')
This will check each view, rule, default, trigger, CHECK constraint, DEFAULT constraint, and stored procedure within your database
Most of this code doesn't work if there are schemas other than "dbo", or if the user's default schema is not "dbo". Here's an update to one of the scripts to fix that:
select t.Table_Schema + '.' + t.table_name
from INFORMATION_SCHEMA.TABLES t
where not exists (
select 1 from INFORMATION_SCHEMA.ROUTINES r
where object_definition(object_id(r.routine_schema + '.' + r.ROUTINE_NAME)) like '%'+t.TABLE_NAME+'%'
) order by t.TABLE_NAME

SQL help - find the table that has 'somefieldId' as the primary key?

How can I search my sql database for a table that contains a field tiEntityId. This field is referenced in a stored procedure, but I am unable to identify which table this id is a primary key for? Any suggestions? I currently look through stored procedure definitions for references to text by using something like this:
Declare #Search varchar(255)
SET #Search='[10.10.100.50]'
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 '%'+#Search+'%'
ORDER BY 2,1
Any SQL guru's out there know what I need to use to find the table that contains the field, preferably the table where that field is the Primary Key.
You can do:
select table_name
from INFORMATION_SCHEMA.COLUMNS
where column_name = 'MyColumn'
If you're looking for primary keys that contain a column with a given name (in SQL 2005+), here you go:
select so.name as TableName,
si.name as IndexName,
sc.name as ColumnName
from sys.indexes si
join sys.index_columns sic
on si.object_id = sic.object_id
and si.index_id = sic.index_id
join sys.columns sc
on si.object_id = sc.object_id
and sic.column_id = sc.column_id
join sys.objects so
on si.object_id = so.object_id
where sc.name like '%ColumnName%'
and si.is_primary_key = 1

How can we check that table have index or not?

How can we check that table have index or not ? if have how to find that index for a particular column for a table?
Regards,
kumar
In SQL Server Management Studio you can navigate down the tree to the table you're interested in and open the indexes node. Double clicking any index in that node will then open the properties dialog which will show which columns are included in the index.
If you would like to use T-SQL, this might help:
SELECT
sys.tables.name,
sys.indexes.name,
sys.columns.name
FROM sys.indexes
INNER JOIN sys.tables ON sys.tables.object_id = sys.indexes.object_id
INNER JOIN sys.index_columns ON sys.index_columns.index_id = sys.indexes.index_id
AND sys.index_columns.object_id = sys.tables.object_id
INNER JOIN sys.columns ON sys.columns.column_id = sys.index_columns.column_id
AND sys.columns.object_id = sys.tables.object_id
WHERE sys.tables.name = 'TABLE NAME HERE'
ORDER BY
sys.tables.name,
sys.indexes.name,
sys.columns.name
ordering by column name is wrong, you need to order by the position in the index, so order by clause should be tabname, indname and sys.index_columns.index_column_id...
Try
select object_name(object_id),* from sys.indexes
where object_name(object_id) = 'your table name'