2011-09-07 4 views
1

상속 된 시스템의 매우 느린 리팩터링 프로세스의 일부로 느린 조인과 하위 쿼리를 제거해야합니다. 필자가 시스템에 익숙해지면서 데이터베이스 구조를 천천히 소독하고, 덕트 테이프 감정을 지우고 점진적으로 개선하면서 그 동안 아무 것도 깨지지 않기를 바란다. 이 중 일부는 세 번째로 연결된 두 테이블의 데이터를 하나로 결합하는 것을 포함합니다.링크 테이블을 통해 한 테이블의 열에서 다른 테이블의 열을 다른 테이블로 복사

테이블 구조는 유사하다 :

CREATE TABLE groups 
(
    group_id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    -- various other fields that are appropriate to groups 
    ... 
    -- these fields need to be filled 
    a ENUM(...) NOT NULL, 
    b INTEGER NOT NULL, 
    c VARCHAR(...) NOT NULL 
); 

CREATE TABLE items 
(
    -- key is determined by an external data source 
    item_id INTEGER NOT NULL PRIMARY KEY, 
    -- various other fields that are appropriate to items 
    ... 
    -- these fields shouldn't be here, but in the groups table 
    a ENUM(...) NOT NULL, 
    b INTEGER NOT NULL, 
    c VARCHAR(...) NOT NULL 
); 

CREATE TABLE group_items 
(
    item_id INTEGER NOT NULL, 
    group_id INTEGER NOT NULL, 
    PRIMARY KEY (item_id,group_id) 
); 

아이템은 하나 개 이상의 그룹 일 수있다. "items"테이블의 각 레코드에는 실제로 항목의 속성이 아닌 항목이 속한 그룹의 열 a, b 및 c에 대한 값이 있습니다. 항목이 다른 그룹에 있으면 값이 다를 수 있으므로 문제가 발생합니다.

거의 완전히 미친 데이터 소스의 미친 가져 오기 프로세스로 채워지므로 항목 테이블에서 필드를 제거 할 수 없습니다. 가져 오기 프로세스를 수정하기 전까지는 items 테이블에 필드가있는 데 방해가되었지만 단기간에 적어도 느린 조회를 제거하여 가져올 수는 있습니다.

지금 당장 나는 각 그룹에서 실행되는 루프가 있으며, 발견되는 첫 번째 항목의 값을 취합니다 (괜찮습니다 - 그룹의 모든 항목은 a, b 및 c에 대해 동일한 값을가집니다) 그룹에 배치합니다. 이 프로세스는 오히려 느리고 힘들며 불행히도 과부하가 걸린 서버에서 자주 실행됩니다. items 테이블의이 값들을 그룹 테이블에 복사하고 MySQL이 PHP 스크립트에 의존하기보다 무거운 작업을 수행하도록하는 현명한 방법이 있습니까?

답변

0

내 대답을 찾은 것처럼 보입니다. 각 그룹의 항목 수는 상대적으로 작은이기 때문에,이 이루어지고 일부 중복 일 수 있지만, 병목 현상과 PHP 루프보다 훨씬 빠른 아니라 수

UPDATE 
    groups g 
    INNER JOIN group_items USING(group_id) 
    INNER JOIN items i USING(item_id) 
SET 
    g.a = i.a, 
    g.b = i.b, 
    g.c = i.c; 

내가 무엇을해야 할 것 같습니다.

관련 문제