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

이 같은:

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

그러나 인덱스의 경우.



답변

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

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


답변

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

INDEXPROPERTY ( object_ID , index_or_statistics_name , property )  

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

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

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


답변

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


답변

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

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

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

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

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


답변

질문의 숨겨진 목적이 큰 테이블을 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] 


답변

색인이 존재하는지 빠르게 확인할 수있는 아래 기능을 작성했습니다. 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를 반환하도록 설정할 수 있지만 유용하지는 않습니다.


답변

-- 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