테이블에 특정 인덱스가 있는지 어떻게 확인합니까?


288

이 같은:

SELECT
* 
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS 
WHERE CONSTRAINT_NAME ='FK_TreeNodesBinaryAssets_BinaryAssets'
and TABLE_NAME = 'TreeNodesBinaryAssets'

그러나 인덱스의 경우.


11
나는 INFORMATION_SCHEMA 실제로 모든 스키마 정보 있었으면 좋겠다
앨런 맥도널드

답변:


480

다음과 같이 간단하게 선택하여 사용할 수 있습니다.

SELECT * 
FROM sys.indexes 
WHERE name='YourIndexName' AND object_id = OBJECT_ID('Schema.YourTableName')

76
명령문을로 랩핑 할 수도 있습니다 IF EXISTS(SELECT * ...) BEGIN ... END.
bounav

26
언급에 그것의 가치 YourTableName스키마 이름이어야한다
마렉

2
@blasto 대부분의 경우와 같이 기본이 아닌 스키마를 사용하는 경우 스키마를 접두사로 지정해야합니다. 다른 경우에는이 쿼리에서 결과를 얻지
Marek

3
임시 테이블을 확인하려면 'tempdb.sys.indexes'및 'tempdb .. # TableName'을 사용할 수 있습니다. (참조 Bjorn D. Jensen )
crokusek

7
"SQL Server 2016부터 DROP INDEX IF EXISTS 구문을 사용할 수 있습니다." MS 문서
heringer

100

를 들어 SQL 2008와 새로운 , 더 간결 방법, 인덱스의 존재를 감지, 현명한 코딩 사용되는 INDEXPROPERTY내장 기능 :

INDEXPROPERTY ( object_ID , index_or_statistics_name , property )  

가장 간단한 사용법은 IndexID속성입니다.

If IndexProperty(Object_Id('MyTable'), 'MyIndex', 'IndexID') Is Null

인덱스가 존재하면 위의 ID를 반환합니다. 그렇지 않으면를 반환 NULL합니다.


71

AdaTheDEV, 나는 당신의 구문을 사용하고 다음과 그 이유를 만들었습니다.

문제점 : 색인 누락으로 인해 한 시간에 1 시간 씩 분기마다 프로세스가 실행됩니다.

수정 : 쿼리 프로세스 또는 프로 시저를 변경하여 인덱스를 확인하고 누락 된 경우 인덱스를 작성하십시오. 쿼리와 프로 시저 끝에 동일한 코드가 배치되어 인덱스가 필요하지 않지만 분기별로 인덱스를 제거합니다. 여기에 드롭 구문 만 표시

-- drop the index 
begin

  IF EXISTS (SELECT *  FROM sys.indexes  WHERE name='Index_Name' 
    AND object_id = OBJECT_ID('[SchmaName].[TableName]'))
  begin
    DROP INDEX [Index_Name] ON [SchmaName].[TableName];
  end

end

15

그러나 원래 질문에서 약간 벗어난 것은 미래에 방문하려는 사람들 DROPCREATE색인, 즉 배포 스크립트에 유용 할 수 있습니다 .

create 문에 다음을 추가하여 존재 확인을 무시할 수 있습니다.

CREATE INDEX IX_IndexName
ON dbo.TableName
WITH (DROP_EXISTING = ON);

자세한 내용은 CREATE INDEX (Transact-SQL)-DROP_EXISTING 절을 참조하십시오.

NB 의견에서 언급했듯이이 절이 오류없이 발생하려면 색인이 이미 존재해야합니다.


8
사실 .. 조심해! 인덱스가 없으면 실패합니다! 적어도 SQL Server 2008에서.
Andrey Kaipov

1
... 그리고 그것은 여전히 SQL 2016에 실패
Magier

2
또 다른 (아마도 명백한) 효과는 항상 인덱스를 다시 생성한다는 것입니다. 이것은 당신이 원하는 것이 아닐 수도 있습니다. 큰 테이블에서 인덱스를 삭제하고 만드는 것은 비용이 많이 드는 작업입니다. 기존 인덱스가 이미 원하는 인덱스 인 경우 특히 그렇습니다. 이 설명은 1 단계 교체에 적합합니다. 그것은 기존의 인덱스를 비교하지 않고 "무차별적인 힘이 존재한다" "존재하더라도 떨어 뜨려 라. 그냥해라!" :-) 여전히 OP가 찾고 있던 모든 검사가 필요합니다. 그러나 인덱스를 교체해야하는 경우 DROP / CREATE를 결합합니다.
ripvlan

10

질문의 숨겨진 목적이 큰 테이블을 DROP만들기 전에 색인 INSERT에 대한 것이라면 이것은 유용한 한 줄짜리입니다.

DROP INDEX IF EXISTS [IndexName] ON [dbo].[TableName]

이 구문은 SQL Server 2016부터 사용할 수 있습니다 IF EXISTS.

https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/11/03/drop-if-exists-new-thing-in-sql-server-2016/

대신 프라이머 키를 다루는 경우 다음을 사용하십시오.

ALTER TABLE [TableName] DROP CONSTRAINT IF EXISTS [PK_name] 

7

색인이 존재하는지 빠르게 확인할 수있는 아래 기능을 작성했습니다. OBJECT_ID와 동일하게 작동합니다.

CREATE FUNCTION INDEX_OBJECT_ID (
    @tableName VARCHAR(128),
    @indexName VARCHAR(128)
    )
RETURNS INT
AS
BEGIN
    DECLARE @objectId INT

    SELECT @objectId = i.object_id
    FROM sys.indexes i
    WHERE i.object_id = OBJECT_ID(@tableName)
    AND i.name = @indexName

    RETURN @objectId
END
GO

편집 : 이것은 테이블의 OBJECT_ID를 반환하지만 인덱스가 없으면 NULL이됩니다. index_id를 반환하도록 설정할 수 있지만 유용하지는 않습니다.


1
-- Delete index if exists
IF EXISTS(SELECT TOP 1 1 FROM sys.indexes indexes INNER JOIN sys.objects 
objects ON indexes.object_id = objects.object_id WHERE indexes.name 
='Your_Index_Name' AND objects.name = 'Your_Table_Name')
BEGIN
    PRINT 'DROP INDEX [Your_Index_Name] ON [dbo].[Your_Table_Name]'
    DROP INDEX [our_Index_Name] ON [dbo].[Your_Table_Name]
END
GO

-1

특정 테이블에 클러스터형 인덱스가 있는지 확인하려면 다음을 수행하십시오.

SELECT * FROM SYS.indexes 
WHERE index_id = 1 AND name IN (SELECT CONSTRAINT_NAME FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE TABLE_NAME = 'Table_Name')

5
기본 키와 고유 제한 조건을 리턴하지만 그 중 어느 것도 반드시 클러스터형 인덱스 일 필요는 없습니다.
Mark Sowul

index_id = 1은 where 절이 올바르지 않습니다. 색인에 다른 ID를 할당 할 수 있습니다
Fuzzybear
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.