2012-05-21 3 views
0

하위 콜이있을 수있는 호출을 모니터링하는 모니터링 응용 프로그램이 있습니다. 따라서 모니터링 데이터를 읽으려면 하위 호출을 포함하여 호출 목록을 얻고 싶습니다. 호출이 무기한 중첩 될 수 있습니다.SQL을 최적화하여 여러 트리를 읽는 방법은 무엇입니까?

- 편집 시작
현재 테스트 테이블에는 약 700 만 개의 항목이 있습니다. 생산적인 사용에서는 배가 된 크기 일 수 있습니다. 루트 입국 당 예상되는 어린이는 0에서 15 세 사이이며, 극소수의 경우 약 50 명의 어린이가있을 수 있습니다. 계층 구조 수준이 매우 낮습니다. 최대 값은 약 5 단계입니다.

다음은 제한된 양의 항목을 내 데이터 모델로 읽는 것입니다. 데이터 모델이나 쿼리를 향상시킬 제안이 있으면 언제든지 알려주십시오.
편집 끝 -

기본적으로 내가 찾은 모든 포럼 항목은 여러 나무 대신 한 트리에서 읽기를 최적화하는 것에 관한 것입니다.

현재, 나는 단지 하나의 테이블과 같이 있습니다

create TABLE montest2 
(
    rootId VARCHAR(45) NOT NULL, 
    messageId VARCHAR(45) NOT NULL, 
    requestMessageId VARCHAR(45), 
    sessionId VARCHAR(45), 
    PRIMARY KEY (messageID) 
); 

rootId 한 트리에 속하는 모든 통화에 대해 동일합니다. sessionId에 값이 있으면 최상위 (루트) 호출임을 알 수 있습니다. messageId는 각 호출마다 고유합니다. requestMessageId에는 부모의 messageId가 포함됩니다.

이제 아이들을 포함하여 처음 5 개의 루트 호출을 읽고 싶습니다. 다음 명령문을 사용하여이 작업을 수행 할 수 있습니다.

편집 :이 쿼리에서 내 문제의 범위를 좁혔습니다. 나는 다른 부모를 선택할 수 있도록 부모를 읽기위한 추가 WHERE 절이있었습니다. 하지만 내 테스트 결과 성능 문제가 발생하지 않았다. (편집의 끝).

  1. 읽기 부모 :

    SELECT am.messageId의 montest2 오전 (am.sessionID가 NULL) FIRST 5 ROWS ONLY

  2. 읽는 어린이 : montest2 FROM

    SELECT ac.messageId ac INNER JOIN (선택 am.rootID FROM montest2 오전 WHERE (am.sessionID IS NOT NULL) FETCH FIRST 5 ROWS ONLY) 부모 ON ac.rootID = parents.rootID WHERE (ac.sessionID가 NULL 임);

많은 문장에서 두 번째 문장이 빠르다는 것을 알고 있습니다. 아무도 내게이 쿼리를 최적화하는 방법에 대한 조언을 줄 수 있습니까? 또는 내 데이터 모델에 대해 무엇을 변경해야합니까?

추신 : 저는 Derby를 데이터베이스로 사용하고 있지만 모든 데이터베이스에서 작동해야합니다. 제한 (첫 번째 x 행 가져 오기) 구문을 변경한다는 의미 일뿐입니다.

+1

'rootId'에 색인을 추가하면 이미 쿼리가 빨라질 것입니다. – sp00m

+0

좋은 제안. 그러나 나는 이미 색인을 가지고 있고 그것은 여전히 ​​너무 느리다 - 더 이상의 팁? – Mgmr

+0

데이터 구조가 실제로 나무가 아닙니다 –

답변

1

다음과 같이 지금 내 문제를 해결 한 : 나는 두 테이블에 모든 항목이 내 하나의 테이블을 분할 한

. 하나의 테이블은 트리의 모든 루트 항목을 포함하고 다른 하나는 모든 하위 항목 (및 하위 항목의 하위 항목 등)을 포함합니다.
첫 번째 쿼리는 루트 테이블에 대해 수행되고, 두 번째 쿼리는 루트 테이블에 대해 수행됩니다. 이제 children 테이블의 크기가 단지 1/4 정도이므로 쿼리가 훨씬 빠릅니다.
또한 인덱스 중 하나가 잘못 정의되어 작동하지 않는다는 것을 알았습니다. DB2 도구를 사용하여 db2 데이터베이스에서 문제점을 시도 할 때 설명을 통해이 사실을 알게되었습니다.

그래서 내 모든 사람들을위한 팁 : 테이블을 작게 유지하고 인덱스가 자신이해야 할 일을 하는지를 설명하는 데 사용하십시오.

0

조인을 where 절로 옮기지 않으려면 왜 이것이 더 좋은지 확인하십시오.

SELECT messageId 
FROM montest2 
WHERE rootID in (
     SELECT rootID from montest2 
     WHERE sessionID IS NOT null 
     FIRST 5 ROWS ONLY) AND 
     sessionID IS NOT null 
+0

이 제안을 해주셔서 감사합니다. 불행하게도, 그것은 성능면에서 차이가 없습니다. 논리적 인 관점에서 볼 때 하위 선택에서 한도를 늘리면 쿼리 속도가 느려지고 느려집니다. 그러나 나는 더 좋은 아이디어를 생각할 수 없다. ... – Mgmr

+0

나는 숫자와 함께 내 질문을 편집하고 내가 성취하고자하는 것을 설명하려고 노력했다. – Mgmr

관련 문제