2012-03-15 3 views
1

StackOverflow에 비슷한 질문이 있지만 테이블에 다른 인덱스를 테스트 한 후에 인덱스가 작동하는 방식을 이해할 수 없다고 생각합니다. 내 쿼리의 성능에서 내가 겪고있는 동작을 설명하십시오. 내가 예를 들어이 쿼리를 사용하고여러 개의 단일 필드 인덱스 대 여러 필드 인덱스

, 나는 상세하게 설명하려고하는거야 :

SELECT ss1.PlayerID, ss1.Name, ss1.Series, ss1.LanesNum, ss1.Date, ss1.LeagueName, ss1.Season FROM SeriesScores ss1 
      JOIN (SELECT Series, Gender, LanesNum, Bowlout, Season FROM SeriesScores 
      WHERE Gender = ? AND LanesNum = ? AND Series > -1 AND Bowlout = 'No' AND Season = '2011-2012' 
      ORDER BY Series DESC LIMIT 0,?) as ss2 
      USING(series, gender, lanesNum, bowlout, season) 
      ORDER BY ss1.Series DESC 

이 쿼리는 각 쌍에 대해 특정 계절에 볼링을 가장 높은 시리즈를 가져 오는 데 사용됩니다 볼링 센터에서 남성과 여성 모두를위한 레인 차선을 확보했습니다.

MAX 집계 함수를 사용하는 대신 자체적으로 테이블에 합류합니다. 지정된 차선 쌍에 매듭이 있으면 모든 이름을 표시해야하기 때문입니다.

기본적으로 내부 SELECT가 반환하는 것과 일치하는 모든 필드를 조인합니다. 그 내부 SELECT는 주어진 젠더와 지정된 레인 쌍에 대한 상위 X 플레이어를 반환합니다.

USING 부분은 동일한 성별, 시리즈, 레인 및 찾고있는 시합과 계절을 선택하지 않은 선수 만 확인합니다. 그런 다음 가장 높은 시리즈에서 가장 낮은 시리즈 순으로 주문합니다.

이 쿼리는 남성 전용 12 회 (볼링 센터에서 12 쌍의 레인) 12 회 및 휠 번호 및 성별 매개 변수 만 변경하여 for 루프에 있습니다.

그런 다음 결과를 응용 프로그램에 표시하기 위해 Java에서 두 가지 다른 벡터에 모든 결과를 넣습니다 (남성 벡터와 여성용 벡터).

인덱스가 없으면 벡터에 결과를 넣는 것을 포함하여 모든 작업을 실행하는 데 약 11 초가 소요됩니다. (남성 12 쿼리는 5.5 초, 여성은 12 초).

(gender, lanesNum, series)에 대한 색인을 사용하면 전체 요구 사항에 대해 0.04 초가 소요됩니다.

그 색인은 WHERE 절에서 사용하는 가장 중요한 필드이기 때문에 사용했지만 다른 것들을 시도하고 실제로 다른 색인을 사용했기 때문에 속도가 향상되는 이유를 알 수 없습니다. 내 쿼리를 100 % 이상 저조하게 만들었습니다. 더구나, 나는 그 색인에 "bowout"와 "season"을 추가하면 더 빠른 쿼리를 얻을 수 있을지 궁금합니다.

먼저 시리즈에서 단일 열 인덱스를 사용해보고 성능을 테스트하고 싶습니다. 이 쿼리는 모두 22 초가 걸리는 인덱스입니다.

인덱스를 사용해야하는 위치와 필드를 여러 개 사용하거나 단일 필드에서 여러 인덱스를 사용해야하는 경우를 이해할 수 없다는 결론에 이르렀습니다. 또한 이해할 수 없습니다. 어떻게 (잘못된) 인덱스를 사용하면 실제로 성능이 저하 될 수 있습니다.

답변

1

하나의 쿼리에 대해 너무 적극적으로 인덱스를 최적화하면 다른 쿼리 (따라서 실제 응용 프로그램 또는 다음 버전)의 속도가 느려질 수 있습니다. 그러나 인덱스 성능을 분석 할 때의 연습 문제와 동일하게 수행하십시오.

인덱스는 여러 가지 방법으로 쿼리 성능에 영향을줍니다. 그것들의 존재는 실제로 데이터베이스 서버가 데이터를 얻기 위해 사용할 알고리즘을 완전히 바꿀 수 있습니다.멋진 개요는 here이지만 쿼리가 간단하고 데이터베이스에 관련 인덱스가 거의 없기 때문에 (테이블의 기본 키를 지원하는 인덱스와 자동 생성 된 인덱스) 데이터베이스를 크게 단순화 할 수 있습니다 .

색인이 좋으면 테이블간에 데이터를 상호 참조하는 것이 더 빠릅니다. 이상적으로는 USING 및 WHERE 절에 열이 포함되어 있으며 대부분 테이블의 고유 한 행을 참조 할만큼 충분합니다. 그 수가 적은 경우 데이터베이스 서버에서 계속 사용할 수 있지만 나머지 행은 하나씩 방문해야합니다.

위대한 색인은 모든 것을 포함 할뿐만 아니라 테이블에서 선택할 모든 데이터도 포함합니다 (예, 두 테이블이 실제로 자체 조인으로 인해 동일한 실제 테이블 인 경우이 의미가 있습니다. 데이터베이스 서버는 부수적으로 동일한 데이터로 두 개의 다른 테이블 인 것처럼 계속 처리합니다. 이러한 "완전 커버 인덱스"의 이점은 데이터베이스 서버가 테이블을 전혀 방문하지 않아도된다는 것입니다. 색인에서 모든 열을 사용할 수 있습니다.

색인과 관련된 항목의 순서. 특히 인덱스의 가장 왼쪽 열이 USING 절 또는 WHERE 절에 나타나야합니다. 그렇지 않으면 단일 색인의 일치 데이터가 해당 색인의 여러 위치에 나타날 수 있으므로 색인은 거의 사용 불가능합니다. 또한 매우 선택적이어야합니다 (표에 여러 가지 값이 있음). 이 첫 손을보기 위해 몇 가지 실험을하십시오.

이러한 이유로, 내가 제안하는 첫 번째 선택 색인은 series, gender, lanesNum, bowlout입니다. 하지만이 쿼리에 대한 귀하의 정보도 매우 훌륭합니다.

명시 적으로 둘 이상의 색인을 만드는 데별로 사용되지 않습니다. 쿼리가 매우 간단하기 때문에 기본적으로 쿼리를 실행하는 동안 두 가지 이상을 사용하지 않습니다. 그래서 가장 유용한 것은 아마 이기고 모든 다른 것들은 무시 될 것입니다.

마지막 질문 : 불필요한 인덱스는 UPDATE, INSERT 및 DELETE 문 (인덱스를 업데이트하기 위해 오버 헤드가 발생하기 때문에)이 느려지는 것으로 생각되지만 그렇게 간단하지는 않습니다. 데이터베이스 서버가 여러 알고리즘을 사용하여 쿼리를 계산할 때 (두 개의 논리 테이블을 사용하고 자동 및 명시 적 인덱스를 사용하거나 사용하지 않을 경우) 잘못된 계획을 선택할 수 있습니다. 인덱스는 데이터를 모른 채 유혹적으로 보일 수 있습니다 분배를 고려할 때 매우 역효과를 가져라.

실제로 데이터베이스 서버가 데이터를 분석하고 몇 가지 통계를 기록하여 후속 쿼리를 합리적으로 최적화하고 쿼리를 22 초 동안 실행하지 않도록 할 수 있습니다 통계가 더 이상 유효하지 않음). 그것이 ANALYZE 명령입니다. 색인을 변경 한 후에 매번 sqlite 성능을 최상으로 볼 수 있도록 발행하십시오. 프로덕션 데이터베이스에서 매일 밤 실행하도록 ANALYZE를 예약하면 데이터베이스가 시간이 지남에 따라 점차적으로 느려지지 않고 무해한 쓸모없는 인덱스를 추가 한 후 갑자기 감속하지 않도록 할 수 있습니다.

+0

매우 명확하고 상세한 답변, 감사합니다! 이 쿼리가 간단하기 때문에 다른 인덱스를 만드는 데별로 사용하지 않는다고 말할 때의 간단한 질문 ... 다른 (때로는 더 복잡한) 쿼리가 있기 때문에 같은 테이블을 사용하는 다른 쿼리에 대한 인덱스를 추가하는 것이 유익합니다. 데이터베이스가 대신 다른 인덱스를 사용해야한다고 생각하면이 쿼리를 느리게 할 수 있습니까? 그 외에는 모든 걸 얻었 어, 고마워. –

+0

처음에 말했듯이, 이것은 단일 쿼리 정신 운동이었습니다. 쿼리가 여러 번 있으면 모든 쿼리에 대해 적절한 성능을 원할 것입니다. 모든 것을 제공 할 수있는 테이블 당 하나의 인덱스가 필요하지만 반드시 그런 것은 아닙니다. 통계가 uptodate되면, u 리를 처음 실행하는 동안 또는 u 리 옵티 마이저 자체가 멋진 작업을 수행하지 못할 경우를 제외하고 추가 인덱스가 속도 저하를 야기해서는 안됩니다. –

+0

@ Adam - 이전 주석에서 언급 한 첫 번째 실행 중 매우 작은 속도 저하는 쿼리를 평가하는 데 사용할 수있는 다양한 알고리즘을 평가하는 쿼리 최적화 프로그램에 대한 것입니다. 그 후,이기는 알고리즘 (이른바 쿼리 플랜)은 동일한 쿼리에 대해 재사용됩니다. –

관련 문제