시작 또는 성능 문제가 발생했을 때 색인을 생성합니까?


15

내 질문은 인덱스 사용에 관한 것입니다.

  1. 처음부터 또는 성능 문제가 발생했을 때 바로 색인 생성을 시작해야합니까?

  2. 쿼리를 실행하는 동안 임시 인덱스를 만들 수도 있습니다. 그러한 기술의 장단점은 무엇입니까?

답변:


17

처음부터 또는 성능 문제가 발생했을 때 바로 색인 생성을 시작해야합니까?

사용 패턴이 등장함에 따라 인덱싱 전략이 발전하는 경향이 있습니다. 즉, 사전에 적용 할 수있는 전략 및 설계 지침도 있습니다.

  • 좋은 클러스터링 키를 선택하십시오 . 일반적으로 테이블에 예상되는 삽입 패턴을 기반으로 디자인 타임에 적절한 클러스터형 인덱스를 결정할 수 있습니다. 미래의 변화에 ​​대한 설득력있는 사건이 발생한다면, 그렇게하십시오.

  • 기본 및 기타 고유 제한 조건을 작성하십시오 . 이들은 고유 인덱스에 의해 시행됩니다.

  • 외래 키 및 관련 비 클러스터형 인덱스를 만듭니다. 외래 키는 가장 자주 참조되는 조인 열이므로 처음부터 색인화하십시오.

  • 매우 선택적인 쿼리에 대한 인덱스를 만듭니다 . 이미 알고있는 쿼리 패턴의 경우 선택성이 높으며 스캔보다는 조회를 사용할 가능성이 높습니다.

위의 내용 외에도 새로운 인덱스를 구현하기위한 점진적이고 전체적인 접근 방식을 취하십시오. 전체적으로, 나는 추가를 평가할 때 모든 쿼리와 기존 인덱스에 대한 잠재적 이점과 영향을 평가합니다.

누락 된 인덱스 DMV 및 SSMS 힌트의 지침으로 인해 SQL Server 서클에서 드문 일이 아닌 문제는 오버 인덱싱입니다. 이러한 도구 중 어느 것도 기존 인덱스를 평가하지 않으며 기존 5 컬럼 인덱스에 단일 컬럼을 추가하는 대신 6 컬럼 인덱스를 새로 작성하도록 제안합니다.

-- If you have this
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
)

-- But your query would benefit from the addition of a column
CREATE NONCLUSTERED INDEX [IX_MyTable_MyIndex] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
    , [col6] ASC
)

-- SSMS will suggest you create this instead
CREATE NONCLUSTERED INDEX [IX_MyTable_AnotherIndexWithTheSameColumnsAsTheExistingIndexPlusCol6] ON [dbo].[MyTable] 
(
    [col1] ASC
    , [col2] ASC
    , [col3] ASC
    , [col4] ASC
    , [col5] ASC
    , [col6] ASC
)

Kimberly Tripp 은 인덱싱 전략에 대한 훌륭한 자료를 가지고 있으며 SQL에 중점을 둔 다른 플랫폼에도 적용 할 수 있습니다. SQL Server 사용자 의 경우 위의 예와 같이 중복을 식별하는 편리한 도구가 있습니다.

쿼리를 실행하는 동안 임시 인덱스를 만들 수도 있습니다. 그러한 기술의 장단점은 무엇입니까?

일반적으로 거의 실행되지 않는 쿼리 (일반적으로 ETL)에만 적용됩니다. 다음을 평가해야합니다.

  1. 인덱스를 만드는 데 걸리는 시간이 쿼리 실행 시간을 줄입니까?
  2. 인덱스를 제자리에 두는 유지 관리 오버 헤드가 필요할 때 생성 / 삭제하는 데 걸리는 시간보다 큽니다.

3
+1 클러스터링 키, 외래 키, 고유 / 기본 키, 누락 된 인덱스 DMV를 액면가로 신뢰하지 않음 ...이 모든 것이 훌륭한 조언입니다. SQL Server에서 기존 인덱스를 다루는 것은 sys.dm_db_index_usage_stats DMV를 사용하여 모니터링하기가 매우 쉽습니다. 일정 기간 동안 스캔하거나 검색하지 않은 인덱스를 나열 할 수 있으며 동일한 인덱스가 여러 번 업데이트 된 것을 확인할 수 있습니다. 이는 오버 인덱싱을 나타냅니다.
매트 M

1
그러나 +1, '명확하게 선택적인 쿼리에 대한 인덱스를 만듭니다.' 다른 모든 시나리오를 다루지는 않습니다. 인덱스는 쿼리가 매우 선택적이지 않더라도 결과를 정렬하는 데 도움이 될 수 있습니다. 선택한 모든 열을 포함하면 쿼리 속도를 높일 수도 있습니다.
Unreason

1
동의했지만 문제는 최종 게임이 아닌 시작점을 찾는 것이 었습니다. 다루지 않는 쿼리를 식별하는 것은 거의 사용 패턴이 없으므로 사용 패턴이 없으면 어렵습니다.
Mark Storey-Smith

8

두 가지 접근 방식과 관련하여 실제로 위험이 있습니다.

옵션 a) 처음부터 색인을 작성했지만 결코 사용되지 않은 많은 색인을 작성했음을 인식하지 못합니다. 이것들은 약간의 오버 헤드를 추가합니다 (데이터를 수정하는 쿼리에 가장 눈에 띄는 것이지만 최상의 인덱스를 식별하려고하는 SELECT 문의 최적화).

더 이상 사용되지 않는 인덱스를 식별하고 인덱스를 제거하려고 시도하도록 스스로 훈련해야합니다 (PostgreSQL이이를 수행 할 수 있습니다. 불행히도 MySQL은 비교할 때 매우 약합니다).

옵션 b) 사람들이 불평하기 시작하거나 진단 도구가 특정 쿼리가 느리고 개선 될 수 있다고 트리거 할 때까지 색인을 추가하지 마십시오.

당신이 소개하는 위험은 인덱스가 필요할 때와 추가해야 할 시점 사이에 시간이 충분하지 않다는 것입니다.

PostgreSQL은 인덱스 생성을 지원하므로이 CONCURRENTLY갑작스러운 인덱스 추가 요구 사항으로 인한 스트레스의 일부를 줄이지 만 매뉴얼 에는 몇 가지주의 사항 이 있습니다.


옵션 (b)는 내가 선호하는 경향이 있지만 두 옵션의 하이브리드가 최선의 해결책이라고 생각합니다. 지수가 실제로 사용될 것이라고 생각하는지 여부는 신뢰 수준과 관련이 있습니다.

이것을 특히 복잡한 토론으로 만드는 것은 일반적으로 인덱스를 변경하기 쉽지만 스키마를 변경하기는 어렵다는 것입니다. 나는 b 의 지연된 반응 을 무모한 변명으로 홍보하고 싶지 않다 .


4

마크의 답변 외에도

예상 수량으로 현실적인 테스트 데이터를 제공함으로써 느낌을 얻을 수 있습니다. 쿼리가 1000 행으로 정상적으로 실행되지만 생산량이 백만이 아닌 많은 (너무 많은) 사례를 보았습니다.

가능하다면 나중에 프로덕션 카피 작업을하십시오.

물론, 다른 모든 것이 동일 할 때 사용 패턴으로 인해 생산 에서만 이상한 문제를 보았습니다.

임시 색인? ETL로드 패턴 외부에서 한 번 필요한 경우 다시 필요합니다. 잊지 마십시오 : 인덱스 생성 / 삭제는 쓰기이며 기록됩니다. = 더 많은로드


3

몇 가지만 추가하면됩니다.

  • 인덱스가 임시 테이블에 있지 않으면 임시 인덱스는 끔찍한 아이디어입니다.
  • 인덱스는 사람들이 인식하는 것보다 훨씬 많은 데이터 공간 (및 기타 오버 헤드)을 차지합니다. 따라서 보수적으로 작성하십시오.

이것이 나의 접근법이다.

  1. Mark와 유사하게 색인이 의미가있는 곳에서 색인을 만드십시오.
  2. 새 색인을 작성하기 위해 성능이 느려질 때까지 기다리지 않아도됩니다. 새 SQL을 작성할 때마다 쿼리 계획을 실행하십시오 (바람직하게는 prod 데이터베이스에 대해). 새 색인이 필요한지 확인할 수 있어야합니다.
  3. 넣어 두려워하지 마십시오 > 0또는 > ""사용하지 않는 컬럼에 대한 어디에 절을한다.

    1. 즉, A, B, C 및 D에 대한 색인이 있다고 가정합시다. 그러나 A, B, D 정보 만 있습니다. 할 수없는 이유가 없습니다.
    select * from blah 
    where A="one" 
    and B="two" 
    and C>=""     --to match index
    and D="four"
    
    --This will use your existing index. No need to create a redundant one.

또 다른 것은 "dba"포럼에 있지만 인덱스 생성은 dba가 아닌 개발자의 책임이어야합니다. (완전히 분리 된 경우)
user606723

2
인덱스가 차지하는 공간에 대한 귀하의 진술은 약간 오도되며 클러스터되지 않은 인덱스에는 오버 헤드가 거의 없습니다. 그 시점에서 질문을 게시 할 수 있다면 더 자세히 살펴볼 가치가 있습니다. 둘째, 인덱스 생성이 개발자의 영역이라는 데 동의하지 않습니다. 개발자와 DBA 간의 ​​협업으로 최상의 결과를 얻을 수있는 영역 중 하나입니다.
Mark Storey-Smith

1
나는 당신에게 우리 테이블 중 하나의 예를 줄 것입니다. 테이블 크기 : 21052404KB 이 테이블에서 하나의 비 클러스터형 인덱스 크기 : 6637470KB. 오버 헤드가 거의 없습니까? 나는 그렇게 생각하지 않는다. 또한 DBA를 공동 작업해서는 안된다고 말하는 것이 아니라 새 인덱스를 만들어야하는지 결정하는 것은 개발자의 책임이어야한다는 것입니다. 그들은 SQL을 작성해서는 안되며 dbas가 이것을 스스로 알아낼 것으로 기대합니다.
user606723

1
문맥이 없으면 숫자를 인용 할 수 없습니다. NC 인덱스 열과 클러스터 키를 지정하지 않으면 오버 헤드와 데이터의 비율을 계산할 수 없습니다.
Mark Storey-Smith

터치 키는 [numeric (24), char, date]이고 NC 열은 [date, numeric (24)]입니다. (이 특정 색인에는 단 두 개의 열).
user606723

2

첫 번째 질문에만 답하려고합니다. 처음부터 일정 시간이 지나면 테이블에 얼마나 많은 레코드가 있을지 대략 추정 할 수 있다면 처음부터 시작하여 일부 색인을 디자인하는 것이 좋습니다. 가장 자주 사용되는 응용 프로그램 호출에 대해 가능한 한 많은 호출을 자동화하는 테스트 도구 또는 테스트 스크립트를 사용하면 처음부터 어떤 테이블 스캔을 피할 수 있는지 알 수 있습니다.

처음에는 추측 작업이 될 것이지만 적절한 사용량 통계가 있으면 이미지가 더 명확 해집니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.