2011-04-13 3 views
0

기호 이름 (예 : 함수)과 시작 메모리 주소 및 끝 메모리 주소 배치가있는 테이블이 있습니다. 이제 시작과 끝 주소 사이에있는 많은 주소를 찾고 각 기호 이름에 매핑하려고합니다 (또는 아래 예제와 같이 시작 주소를 더 간단하게 지정).선택한 수백만 개의 값을 포함하는 최소 및 최대 범위 값을 갖는 행을 찾습니다.

나는 이런 식으로 쿼리를 수행

SELECT r.caller_addr AS caller_addr,sm.addrstart AS caller FROM rets AS r 
JOIN symbolmap AS sm ON r.caller_addr BETWEEN sm.addrstart AND sm.addrend; 

RETS 약 백만 caller_addr을 포함하는 테이블입니다. symbolmap 테이블로 작성된다 : 임의의 (이 예에서는 r.caller_addr) ADDR 요청을 위해 행이 없음 중첩 없다 addrend하는

CREATE TABLE 
    symbolmap 
    (addrstart BIGINT NOT NULL, 
    addrend BIGINT NOT NULL, 
    name VARCHAR(45), 
    PRIMARY KEY (addrstart), 
    UNIQUE INDEX (addrend)) ENGINE = InnoDB; 

모든 addrstart을, 즉 하나의 행만 히트가있을 수있다. symbolmap 테이블에는 42000 개의 행이 있습니다. 몇 가지 다른 인덱스 방법을 시도했지만 여전히 선택 시간이 매우 오래 걸리고 (수십 분의 시간이 걸립니다) 끝까지 관리하지 못했습니다.

성능이 좋은 인덱스 또는 다른 선택문에 대한 제안 사항이 있습니까? 나는 이것을 MySQL 5.1.41에서 돌리고 있으며 이식성에 대해 걱정할 필요가 없다.

다른 사람들이 무엇을 검색했는지에 따라 나는 일정한 경계가있는 결과 만 찾고 올바른 경계를 가진 행을 찾을 때가 아닙니다. 그러나 그것은 아주 일반적인 문제처럼 보입니다.

+0

BIGINT되어 있는지 확인합니다 . – zerkms

+0

은 관계를 지정하는'r.caller_addr BETWEEN sm.addrstart AND sm.addrend'가 아닙니까? – Harald

답변

0

봅니다 단일 인덱스에있는 두 개의 열을 결합 :

또한
CREATE TABLE 
    symbolmap 
    (addrstart BIGINT NOT NULL, 
    addrend BIGINT NOT NULL, 
    name VARCHAR(45), 
    PRIMARY KEY (addrstart, addrend) 
) ENGINE = InnoDB; 

하는 caller_addr 또한 당신은 당신의`r`과`sm` 테이블 간의 관계를 지정하는 조건을 놓친

+0

팁 주셔서 감사합니다, 나는 시간을 잰 적이 없지만 결합 된 색인으로 향상시키는 것 같습니다. 수만 개의 별개의 임시 테이블을 만들어 주소가있는 수백만 행의 주요 문제를 해결하기로 결정했습니다. 그런 다음 위의 선택 쿼리에서 다른 임시 테이블을 만듭니다. 이 마지막 테이블을 사용하여 수백만 행의 기호에서 기호로 직접 간단한 등호 결합을 수행 할 수 있습니다. 내 컴퓨터에서 30 초 정도면 훨씬 빨라졌습니다. – Harald

관련 문제