2012-04-18 2 views
0

우리는 내가 몇 가지 제안을 (우리는 오라클 10g R2에있는) 상황이오라클 DB 성능 튜닝

1과 같은 s 번째입니다) 그것은 레거시 시스템이 필요 성능 문제로 실행하고 있습니다.

2) 일부 표에는 지난 10 년 동안의 데이터가 저장되어 있습니다 (첫 번째 버전이 출시 된 이후로 데이터가 삭제되지 않았다는 의미입니다). 이제 대부분의 OLTP 테이블에서 약 30,000,000 ~ 40,000,000 개의 행이 있습니다.

3) 이러한 테이블에 대한 검색 작업은 5-6 분 정도 소요됩니다. (xxxxx에서 select count (0)와 같은 간단한 쿼리 인 isActive = 'Y'는 6 분 정도 소요됩니다.) Explain 계획을 보았을 때 isActive 열에서 인덱스 스캔이 발생하는 것으로 나타났습니다.

4) 우리는 필요하지 않은 이전 데이터를 보관 및 삭제하고 팀이이를 위해 노력하고 있음을 제안했습니다. 5 년 동안의 데이터를 삭제하더라도 테이블에 약 15,000,000 ~ 20,000,000 개의 행이 남아 있기 때문에이 테이블에 테이블 분할 기능이 있다고 생각했지만 사용자는 이 테이블의 열을 UI에서 가져 오면 테이블 파티셔닝의 목적을 뛰어 넘을 것입니다.

이 상황을 개선하기 위해 수행해야 할 단계는 무엇입니까?

+1

"활성"인 20mm 레코드 중 10mm가있는 경우 FTS가 발생하지 않을 것이라는 점에 놀랐지 만 그러한 쿼리에는 다소 시간이 걸린다는 것은 놀라운 일이 아닙니다 (oltp 유형이 아님) 쿼리, 자세한 배치/보고서 유형). 대부분 일괄 처리/보고서 유형 쿼리에 대한 우려가 있습니까? – tbone

+0

아마도이 질문을 살펴볼 가치가 있습니다. 본질적으로 똑같은 것입니다. http://stackoverflow.com/questions/2030011/how-to-index-y-n-column-in-oracle –

+0

1) 어떤 유형의 인덱스 스캔입니까? 빠른 전체 인덱스 스캔, 인덱스 범위 스캔, 다른 것? 2)이 테이블에 대한 좋은 통계가 있습니까? 3) 5 년의 데이터를 삭제하는 프로세스에 따라 10 년의 데이터를 저장할 공간이있는 테이블과 인덱스가 남아있을 수 있습니다. 이렇게 빠른 전체 인덱스 스캔과 전체 테이블 스캔은 여전히 ​​많은 블록을 읽어야합니다. 4) isActive의 어떤 비율이 'Y'입니까? –

답변

4

먼저 질문 : select count(0) from xxxxx where isactive = 'Y'을 처음으로 발행하는 이유는 무엇입니까? 10 번 중 9 번은 기록의 유무를 확인하는 게으른 방법입니다. 그럴 경우, 1 행 (rownum = 1 및 first_rows 힌트)을 선택하는 쿼리로 바꾸십시오.

언급 한 행의 수는 걱정할 필요가 없습니다. 행 수가 증가 할 때 응용 프로그램이 잘 수행되지 않으면 시스템이 확장되도록 설계되지 않은 것입니다. SQL * Trace 또는 ASH를 사용하여 너무 오래 걸리는 모든 쿼리를 조사하고 수정했습니다.

덧붙여서 언급 한 내용은 유산이라는 용어를 정당화하지 않습니다.

감사합니다.
Rob.

1

불과 몇 관찰 : - 'Y'와 'N'(혹은 'Y', 'N', 그리고

  1. 본인은 "이 isActive"열 두 개의 값을 가질 수 있습니다 같은데요 NULL - 비록 Fred의 이름에서 NOT NULL 제약 조건이 없다면 그러한 열은 나를 벗어난다.). 이 경우이 열의 색인은 선택성이 매우 떨어지며 색인이 없으면 더 좋을 수 있습니다. 색인을 삭제하고 쿼리를 다시 실행하십시오.

  2. @ RobVanWijk의 SELECT COUNT(*)에 대한 사용 후기가 우수합니다. 카운트가 실제로 필요한 경우에만 행 카운트를 요청하십시오. 카운트가 필요하지 않다면, SELECT COUNT(*)을 수행하는 것보다 apprpriate 예외 핸들러가있는 직접 프로브 (SELECT whatever FROM wherever WHERE somefield = somevalue)를 수행하는 것이 더 빠르다는 것을 발견했습니다.당신이 인용 된 경우에, 나는 분할에 관해서는

BEGIN

SELECT IS_ACTIVE 
    INTO strIsActive 
    FROM MY_TABLE 
    WHERE IS_ACTIVE = 'Y'; 

    bActive_records_found := TRUE; 
EXCEPTION 
    WHEN NO_DATA_FOUND THEN 
    bActive_records_found := FALSE; 
    WHEN TOO_MANY_ROWS THEN 
    bActive_records_found := TRUE; 
END; 
  1. 처럼 뭔가를 더 좋을 거라 생각 - 분할이 효과적 일 수 쿼리 시간 분야 IF를 줄이는 테이블이 파티션 된 모든 쿼리에서 사용됩니다. 예를 들어 테이블이 TRANSACTION_DATE 변수로 분할 된 경우 분할로 인해이 테이블에 대한 모든 쿼리가 WHERE 절에서 TRANSACTION_DATE 테스트를 수행해야합니다. 그렇지 않으면 데이터베이스가 쿼리를 만족시키기 위해 각 파티션을 검색해야하므로 어떤 개선점이 있는지 의심 스럽습니다.

공유하고 즐기십시오.

+0

위의 쿼리를 사용하여이 기준을 충족하는 테이블에 레코드가 몇 개 있는지 확인합니다. 이 isActive 열은 'Y'또는 'N'의 두 값만 갖습니다. – Ravi

+0

이 경우 IsActive 열에 테이블의 기본 키를 더한 인덱스를 변경해보십시오. –

+0

isActive 열에 인덱스가 있습니다. – Ravi