2012-10-30 3 views
0

기본적으로 내 문제는 제가 17000000 개 정도의 제품으로 구성된 대규모 테이블을 가지고있어 많은 업데이트를 신속하게 적용해야한다는 것입니다.Mysql InnoDB와 신속하게 대형 업데이트 적용

테이블에 int (10) AUTO_INCREMENT로 설정된 ID가있는 열이 30 개 있습니다.

이 테이블에 대한 모든 업데이트가 저장되는 다른 테이블이 있습니다.이 업데이트는 계산하는 데 며칠이 걸리므로 미리 계산해야합니다. 이 테이블의 형식은 [product_id int (10), update_value int (10)]입니다.

이 1700 만 건의 업데이트를 신속하게 발표하기 위해 취하는 전략은 이러한 모든 업데이트를 루비 스크립트의 메모리에로드하고 배열의 해시로 그룹화하여 각 update_value가 키이고 각 배열이 정렬 된 product_id의 목록.

{ 
    150: => [1,2,3,4,5,6], 
    160: => [7,8,9,10] 
} 

업데이트는 그때 PRODUCT_ID 년대의 분류 배치에 업데이트를 실행하는 것이 최적의 방법이 될 것을 나는 의미에서 올바르게하고 있어요 확신

UPDATE product SET update_value = 150 WHERE product_id IN (1,2,3,4,5,6); 
UPDATE product SET update_value = 160 WHERE product_id IN (7,8,9,10); 

의 형식으로 발행된다 mysql/innodb와 함께 해보자.

1300 만개의 레코드를 업데이트 할 때 테스트 할 때 약 45 분이 소요되는 이상한 문제가 발생했습니다. 이제 나는 더 많은 데이터, 약 1,700 만 건의 레코드로 테스트하고 있으며 업데이트는 120 분 가까이에 있습니다. 나는 여기에 어떤 종류의 속도 저하가있을 것이라고 기대 했었지만 내가 보는 정도는 아니었다.

내가이 속도를 높이거나이 더 큰 레코드 세트로 나를 감속시킬 수있는 방법에 대한 조언이 있으십니까?

서버 사양이 올라간다면 메모리/CPU 용량이 꽤 많으며 전체 DB는 메모리가 충분 해져야 성장할 수 있습니다.

+1

innodb_ * 설정을 조정하여 "메모리 힙"을 활용할 수 있습니까? – hexist

+0

그래, 서버 직원들은 꽤 잘 조정했다. – Marklar

답변

0

당신은 MySQL의의 멀티 테이블 업데이트 구문을 사용하여 시도 할 수 있습니다

update product, sometable SET product.update_value=sometable.value WHERE product_id=sometable.whatever; 

은 MySQL이

0

을 통해 연마 할 수있는 데이터베이스와 하나의 큰 쿼리를 통해 단일 패스의 그런 식으로 생각 신중을 필요 설계 색인 및 데이터 페이지 액세스.

쿼리에서 product_id s '배포가 무작위라고 가정하면 각 업데이트 SQL은 임의의 인덱스 페이지 액세스를 유발합니다. 물론 인덱스 페이지 액세스를 따르는 데이터 페이지 액세스도 무작위입니다. 모든 업데이트를 빠르게 실행하려면 모든 인덱스 페이지를 메모리에 저장해야합니다 (최소한). 업데이트 작업이 빠르지 않습니다.

나는하지 트랜잭션이 같은 product_ids 당 나는 하나의 모든 행, 하나를 업데이 트됩니다, 트랜잭션이 요구 IT 및 업데이트를하지 설계하고있어 경우

UPDATE product SET update_value = 150 WHERE product_id = 1 
UPDATE product SET update_value = 150 WHERE product_id = 2 
... 

이후 것 인덱스 페이지와 데이터 페이지가 순차적으로 읽거나 업데이트되도록하기 위해이 스키마는 캐시 관리 관점에서 업데이트는 더 길지만 비용은 훨씬 저렴할 수 있습니다. 물론 데이터베이스에 대한 전반적인 영향은 최소화되므로 업데이트 이외의 작업 (예 : 고객의 쿼리)이 저하되지 않습니다.

트랜잭션 작업이 필요한 경우, 아마도 두 개의 테이블이 필요하거나 위의 캐시 논의 관점에서 더 저렴한 하나의 테이블에 두 개의 논리 테이블을 갖기 위해 트릭을 사용해야합니다. 그러나 트랜잭션이 필요하지 않다면 product_id 당 느린 업데이트가 가야합니다.

관련 문제