-- 퍼옴.
/*
Find Duplicate Indexes
This script returns the Duplicate indexes on any database
I use 2 User defined Functions
Compatible with SQLServer 2000 (I used sp3)
It won't work in SQL Server 7.0 because It uses user-defined functions and a Memory.
Created by G.R. Preethiviraj Kulasingham
pkulasingham@virtusa.com
Written on : February 20, 2003
Modified on : May 18, 2004
Additional code written to remove duplicate entries.
Additional code to include index properties.
*/
IF EXISTS(Select id from sysobjects Where id = object_id('dbo.GetColID'))
DROP FUNCTION dbo.getColID
GO
Create Function dbo.getColID (@TableID int, @indid int)
/*
Parameters:
@TableID: ID of the Table
@IndID : ID of the Index
Returns All the Columns (ID) for the given index in string format seperated by '&'sign. '-' is added for descending keys
*/
Returns Varchar(200)
As
BEGIN
Declare @SQL varchar(200)
Set @SQL =''
Select @SQL= @SQL +'&'+ convert(varchar(7),((indexkey_property(id, indid, keyno, 'isdescending')*-2)+1)* colid) from sysindexkeys
Where id =@Tableid and indid=@Indid
Order by id, indid, Keyno
IF LEN(@SQL)>1
Select @SQL = @SQL +'&'
Return @SQL
END
GO
IF EXISTS(Select id from sysobjects Where id = object_id('dbo.GetColList'))
DROP FUNCTION dbo.getColList
GO
Create Function dbo.getColList (@Tableid int, @indid int)
/*
Parameters:
@TableID: ID of the Table
@IndID : ID of the Index
Returns Index Key (column names) for the given index in string format seperated by commas.
*/
Returns Varchar(8000)
As
BEGIN
Declare @SQL varchar(8000)
Set @SQL =''
Select @SQL= @SQL +', '+ INDEX_Col(User_name(ObjectProperty(@TableID, 'Ownerid'))+'.'+Object_name(@TableID), @indid, keyno)+
Case indexkey_property(id, indid, keyno, 'isdescending') When 1 Then '(Desc)' Else '' end from sysindexkeys
Where id =@Tableid and indid=@Indid
Order by id, indid, Keyno
IF LEN(@SQL)>2
Select @SQL = SUbString(@SQL, 3, LEN(@SQL)-2)
Return @SQL
END
GO
/*
@TempTable is used to store the keys in long string format
*/
Declare @TempTable Table (
ID int ,
Indid int,
ColID Varchar(200),
Status int
)
Declare @Duplicates Table (
LineID int Identity(1,1),
ID int ,
hasClustered char(3) not null default('NO'),
Indid1 int,
ColID1 Varchar(200),
Status1 int,
Desc1 varchar(200),
IndID2 int,
ColID2 Varchar(200),
Status2 int,
Desc2 varchar(100)
)
Insert into @TempTable
Select Id, indid, dbo.GetColid(id, indid), status from Sysindexes
where (status & 64)=0
order by id
Delete @TempTable Where ColID=''
Insert into @Duplicates (ID, IndID1, ColID1, Desc1, Status1, IndID2, ColID2, desc2, status2 )
Select A.ID, A.IndID, A.ColID, '', A.status, B.IndID, B.ColID, '', B.status
from @Temptable A, @TempTable B
Where A.id = b.id and a.indid<>b.indid and
a.colid like b.colid
+'%'
--This part removes the duplicate entries.
Delete @Duplicates Where LineID In (
Select A.LineID from @Duplicates A, @Duplicates B
Where A.ID = B.ID and A.IndID1= B.IndID2 and A.IndID2= B.IndID1 and A.LineID>B.LineID)
Delete @Duplicates Where LineID In (
Select A.LineID from @Duplicates A, @Duplicates B
Where A.ID = B.ID and A.IndID1 = B.IndID2 )
-- Identify the index properties
Update @Duplicates Set Desc1 =CASE status1 & 16 WHEN 0 THEN 'Nonclustered' ELSE 'Clustered' END
Update @Duplicates Set Desc2 =CASE status2 & 16 WHEN 0 THEN 'Nonclustered' ELSE 'Clustered' END
Declare @Desc varchar(20), @Number int
Declare spt_Vals Cursor
FOR
Select name, number from master.dbo.spt_Values
Where type ='I' and number in (1,2, 4, 32, 2048, 4096)
Order by number
Open spt_vals
FETCH Next from spt_vals into @Desc, @Number
WHILE @@FETCH_STATUS=0
BEGIN
Update @Duplicates Set Desc1 = Desc1 + ', '+ @Desc
where status1 & @number <>0
Update @Duplicates Set Desc2 = Desc2 + ', '+ @Desc
where status2 & @number <>0
FETCH Next from spt_vals into @Desc, @Number
END
CLOSE spt_Vals
DEALLOCATE spt_vals
Update @Duplicates Set Desc1 = replace(Desc1, 'unique, primary key', 'primary key'),
Desc2 = replace(Desc2, 'unique, primary key', 'primary key')
Update @Duplicates Set Desc1 = replace(Desc1, 'unique, unique key', 'unique key'),
Desc2 = replace(Desc2, 'unique, unique key', 'unique key')
-- Identify whether table has clustered index
Update @Duplicates Set HasClustered = 'YES' Where id in (
Select id From sysIndexes Where IndId=1)
--Update @Duplicates Set HasClustered = 'NO' Where id in (
--Select id From sysIndexes Where IndId=0)
Select User_name(ObjectProperty(A.ID, 'Ownerid'))+'.'+Object_name(a.id) 'Table Name', HasClustered,
IA.Name 'Index 1', dbo.GetColList(A.id, A.indid1) 'Keys of Index 1', A.Desc1 'Desc 1',
IB.Name 'Index 2', dbo.GetColList(A.id, A.indid2) 'Columns of Index 2', A.Desc2 'Desc 2'
from @Duplicates A, SysIndexes IA, Sysindexes IB
Where IA.id =A.id and IA.indId = A.IndID1 and IB.ID = A.ID and IB.indId=A.IndID2
order by User_name(ObjectProperty(A.ID, 'Ownerid'))+'.'+Object_name(a.id)
/*
GO
DROP FUNCTION dbo.getColList
GO
DROP FUNCTION dbo.getColID
GO
*/
'Database Administrator > T-SQL' 카테고리의 다른 글
| SQLCLR Disk 사이즈 확인 (0) | 2011.08.14 |
|---|---|
| T-SQL:: TCP 포트 정보 (0) | 2011.08.13 |
| DBCC ShrinkFile (0) | 2010.09.06 |
| [T-SQL] JOb 수행 시간 완료 계산 (0) | 2010.07.19 |