2008-10-31 2 views
25

"조기 최적화는 모든 악의 근원 인 작은 효율, 즉 약 97 %의 시간을 잊어 버려야합니다." (Donald Knuth). 내 SQL 테이블은 각각 ​​수천 개가 넘는 행을 포함하지는 않습니다 (그리고 그것들은 큰 것들입니다!). SQL Server 데이터베이스 엔진 튜닝 관리자는 데이터 양을 부적절한 것으로 처리합니다. 그래서 나는이 테이블에 명시적인 인덱스를 두는 것에 대해서 생각하지 않아야한다. 옳은?작은 테이블에 인덱스가 없습니까?

답변

31

색인의 속도는 읽기 속도를 높이는 데 사용됩니다. 예를 들어 날짜 열의 날짜 범위를 기반으로 많은 SELECT를 수행하는 경우 해당 열에 인덱스를 추가하는 것이 좋습니다. 그리고 물론, 일반적으로 중요한 모든 빈도로 JOINING 할 모든 열에 인덱스를 추가합니다. 효율성 증가는 일반 레코드 세트의 크기 대 레코드 수의 비율과 관련이 있습니다 (즉, 20/2000 레코드를 잡는 것은 90/100 레코드를 가져 오는 것보다 색인 생성의 이점이 많음). 색인화되지 않은 열에 대한 조회는 본질적으로 선형 검색입니다.

모든 INSERT에 각 열 인덱스에 대한 내부 삽입이 필요하기 때문에 인덱스 비용이 발생합니다.

따라서 답변은 전적으로 귀하의 응용 프로그램에 달려 있습니다. - 읽기 횟수가 100 배 또는 1000 배가되는 동적 웹 사이트와 같이 데이터 열을 기반으로 자주 조회하는 경우 색인 생성 잘 유익 할 수도 있습니다. 그러나 글을 읽는 것보다 읽기가 훨씬 많으면 튜닝이 속도를 높이는 데 집중해야합니다.

JOIN/WHERE 열에서 인덱스가 있거나없는 앱의 가장 자주 수행되는 작업을 식별하고 벤치마킹하는 데 약간의 시간이 걸리므로 권장합니다. 또한 프로덕션 응용 프로그램을 모니터링하고 가장 비싸고 가장 자주 발생하는 쿼리를 식별하고 이러한 두 쿼리 집합의 교차점에 최적화 노력을 집중시키는 것이 현명한 방법입니다 (색인 또는 완전히 다른 것을 의미 할 수도 있음). 쿼리 또는 조인).

+1

테이블이 충분히 작고 클러스터 된 인덱스 (일반적으로 기본 키)가 있고 커버 리지 인덱스가 쿼리를 만족하지 않으면 SQL Server 최적화 프로그램은 인덱스를 사용하지 않습니다. 대신 테이블 스캔을 수행합니다. 이것은 클러스터 된 인덱스에 대한 예약 조회가 비용이 많이 든다는 사실 때문입니다. –

+1

의미가 있습니다 ... 행 데이터는 클러스터 된 인덱스의 리프 노드에 저장되므로 SQL은 인덱스 조회 또는 테이블 스캔 (대략적으로 말하면)을 통해 동일한 페이지를 검색합니다. 선형 스캔 대신 b- 트리 검색을 가능하게하는 비 PK 컬럼의 비 클러스터형 인덱스에 좀 더 일반적으로 응답하고있었습니다. – joelhardi

+0

이 테이블을 사용하는 명령문에 의해 생성되는 논리 읽기의 수에 따라 다릅니다. 테이블이 잘못 쿼리 된 경우, 인라인 테이블을 읽는 함수를 호출하여 인수에 대해 말하면 작은 테이블의 경우에도 많은로드가 끝날 수 있습니다. 나는 질의 계획을보고 set statistics IO를 사용하여 작은 테이블에서 얼마나 많은 디스크 읽기가 생성되는지 검사 할 것이다. 인덱스가 많지 않고 쿼리의 이러한 부분이 쿼리 계획에 비용이 적게 든다면 인덱스에는 거의 문제가 없을 것입니다. 결론 - 테이블이 쿼리되는 방식에 따라 다릅니다. –

3

행의 너비가 좁고 10-20 개의 8K 페이지에 수천 개의 행이 들어있는 경우 SQL 최적화 프로그램이 인덱스를 작성하더라도이를 사용하도록 선택하지는 않습니다.

0

데이터의 수가 적은 테이블을 쿼리 할 때 충분해야하는 테이블의 기본 키에 자동 인덱싱이 있다고 생각됩니다.

그래야 작업 할 작은 데이터 세트가있는 경우 명시 적 색인을 피할 수 있습니다. 당신이 :)해야 할 경우에만

1

넣고 인덱스
표가 ...
그래서, 다른 말로하면, 당신은 퍼팅에 대해 생각 사용되는지에 따라 퍼팅 인덱스가 실제로 성능을 해칠 수있는 시간이 있습니다 응용 프로그램을 프로파일 링하여 결정할 때 필요한 경우 테이블에 대한 색인입니다.

+0

테이블에 인덱스를두면 성능이 어떻게 저하 될 수 있습니까? –

+1

인덱스는 쓰기 작업 속도를 늦 춥니 다 (인덱스도 업데이트해야하고 해당 업데이트를 어느 시점에서 디스크로 플러시해야 함) 인덱스가 디스크 및 메모리의 공간을 차지하므로 나중에 더 많은 스와핑이 발생할 수 있습니다 이는 성능 저하를 유발할 수 있습니다. – Tyrael

1

인덱스는 종종 UNIQUE 제약 조건을 사용할 때 암시 적으로 만들어집니다. 나는 그 경우에 그들의 사용을 피하려고 노력하지 않을 것이다!

+0

공정한 포인트. "명시 적 색인"이라고 말하기 위해 질문을 편집했습니다. – onedaywhen

+0

UNIQUE 제약 조건을 추가하면 데이터베이스는 항상 "자주"가 아니라 인덱스를 추가합니다. –

7

기본 키 열에는 고유 제한 조건에 대한 색인이 생성됩니다. 나는 여전히 모든 외래 키 열을 색인화합니다. 옵티마이 저는 관련이없는 경우 색인을 무시하도록 선택할 수 있습니다.

데이터가 조금 밖에없는 경우 삽입/업데이트를위한 추가 비용이 중요하지 않습니다.

4

절대 올바르지 않습니다. 100 % 잘못되었습니다. 백만 개의 무의미한 인덱스를 두지 말고 기본 키 (대부분의 경우)를 원한다면 올바르게 클러스터되기를 원할 것입니다.

SELECT * FROM MySmallTable <-- No worries... Index won't help 

SELECT 
    * 
FROM 
    MyBigTable INNER JOIN MySmallTable ON... <-- Ahh, now I'm glad I have my index. 

여기로 갈 수있는 좋은 규칙이있다 : 왜

는 여기에 있습니다.

"테이블이 있기 때문에 언젠가는 쿼리하고 싶을 것입니다. 쿼리를 수행한다면 일관된 방식으로 그렇게 할 것입니다. "< - 이것이 테이블의 색인을 생성하는 방법입니다.

EDIT : 구체적인 예를 염두에두면 다음과 같이 추가 할 예정입니다. 색인을 생성하는 방법과 비용을 절감 할 수있는 방법을 알려 드리겠습니다. 표를 제공하고 그 표를 어떻게 사용할 계획인지 예를 제시하십시오.

5

다릅니다. 테이블이 참조 테이블입니까?

색인이없고 결과 테이블 스캔이 사용자를 5 초가 아닌 5 초 지연시키는 상당히 간단한 작업 사이의 차이를 만들 수있는 1000 개의 행이있는 테이블이 있습니다. SQL Server 이외의 DBMS를 사용하여이 문제를 정확하게 파악했습니다.

일반적으로 테이블이 참조 테이블이면 업데이트가 상대적으로 드뭅니다. 즉, 인덱스를 업데이트 할 때 발생하는 성능 저하는 비교적 드뭅니다. 옵티마이 저가 인덱스를 넘으면 옵티마이 저의 성능이 무시됩니다. 색인을 저장하는 데 필요한 공간도 무시할 수 있습니다.

기본 키를 선언하는 경우 해당 키에 대한 자동 인덱스를 가져야합니다. 이 자동 색인은 거의 항상 비용을 정당화 할만큼 충분히 당신을 할 것입니다. 그것을 거기에 맡기십시오. 기본 키가없는 참조 테이블을 만드는 경우 디자인 방법론에 다른 문제가 있습니다.

기본 키 이외의 일부 열 집합에서 자주 검색하거나 자주 조인하는 경우 추가 인덱스가 자체적으로 비용을 지불 할 수 있습니다. 문제가 아닌 이상 문제를 해결하지 마십시오.

다음은 일반적인 경험 법칙입니다. 이유가없는 한 DBMS의 기본 동작으로 이동하십시오. 다른 부분은 귀하의 부분에 대한 최적화가 너무 이른 것입니다.

4

색인 작성에 대한 일반적인 규칙을 따르는 것이 좋습니다. 이는 대략 "사용자 쿼리에서 사용하는 열에 색인을 작성"하는 것을 의미합니다.

이렇게 작은 데이터베이스에서는 불필요하게 들릴 수 있습니다. 다른 사람들이 이미 말했듯이, 데이터베이스가 설명대로 작게 유지되는 한 쿼리는 충분히 빠르며 인덱스는 실제로 필요하지 않습니다. 그것들은 심지어 삽입과 업데이트 속도를 늦출 수 있지만, 매우 구체적인 요구 사항이 없으면 그러한 작은 데이터베이스에서는 중요하지 않습니다.

데이터베이스가 커지면 (때로는 어떤 데이터베이스가 그렇게되는 경우도 있음) 이전에 잊어 버렸던 이전 데이터베이스에 인덱스를 추가하는 것을 기억할 필요가 없습니다. 어쩌면 고객에게도 설치되어있을 수 있으며 수정할 수는 없습니다!

제가 말하고자하는 것은 인덱스가 데이터베이스 디자인의 자연스러운 부분이어야하며 이 부족하다는 것입니다. 인덱스가 최적화 된 것인지,시기 적절하지 않은지 여부입니다.

0

인덱스가있는 경우에도 SQL Server는 해당 테이블에 대한 통계에 따라 인덱스를 사용하지 않을 수도 있습니다.그리고 일 년에 최대 두 번 실행되는 보고서의 색인을 작성할 계획이라면 색인을 추가하는 INSERT/UPDATE 페널티는 사실상 항상 유효합니다. 인덱스를 추가하기 전에 성능 저하의 가치가 있는지 스스로에게 자문 해보십시오. 당신은 DBMS를 최적화가 사용이 일부 쿼리를 최적화 할 수 있다는 인덱스를 제공하고 있습니다 :

8

크 누스의 지혜로운 말은 인덱스를 추가하여이 하지 직접 무엇을 최적화하기 때문에, 인덱스의 생성에 적용 (여부)하지 . 실제로, 이 아닌 작은 테이블을 인덱싱하는을 결정하는 것이 DBMS 옵티 마이저의 옵션을 제한하는 것과 같은 조숙 한 최적화라고 주장 할 수 있습니다!

다른 DBMS는 테이블 크기를 비롯한 다양한 요인에 따라 열을 인덱싱할지 여부를 선택하기위한 여러 가지 지침을 가지며이를 고려해야합니다.

무엇이 데이터베이스의 조숙 한 최적화 예제 : 벤치마킹 전에 정규화 된 데이터베이스에 실제로 성능 문제가 있음을 나타 내기 전에 "성능에 대한 비정규 화"가 있습니다.

1

대개의 경우, 작은 인덱스는 일반적으로 사용되지 않으므로 피하는 것이 좋습니다.

그러나 때로는 내가 here으로 개괄 한대로 거대한 부스트를 제공 할 수 있습니다.

0

쿼리를 기반으로 두 개의 조회가 행에 대한 포인터를 얻기 위해 색인으로, 행 자체 옆에 두 개의 조회가 수행 될 수 있다는 것을 알아야합니다. 쿼리되는 데이터가 인덱스 열에 있으면 추가 단계가 필요하지 않을 수 있습니다.

옵티마이 저가 색인을 수행하더라도 데이터에 대한 이중 디핑이 더 느려질 수 있습니다. 우리가 관심을 갖는지 여부는 응용 프로그램 프로파일 링 및 최종 설명 계획에 달려 있습니다.

관련 문제