2009-08-17 5 views
2

MySQL 테이블에 필드를 추가했습니다. 새 열을 다른 테이블의 값으로 채워야합니다. 다음은 실행할 쿼리입니다.750k 행에 MySQL 업데이트 쿼리를 실행하십시오.

UPDATE  table1 t1 
SET   t1.user_id = 
         (
         SELECT t2.user_id 
         FROM  table2 t2 
         WHERE t2.usr_id = t1.usr_id 
         ) 

이 쿼리는 239K 행에서 로컬로 실행되었으며 약 10 분이 걸렸습니다. 실제 환경에서 그렇게하기 전에 내가하고있는 일이 괜찮은지, 즉 10 분이 합리적으로 들리는 지 물어보고 싶었습니다. 아니면 다른 방법으로해야합니까, PHP 루프? 더 나은 쿼리? 누락 된 정보의이 개 오히려 중요한 부분이 있습니다

답변

6

UPDATE JOIN! 이렇게하면 모든 피 묻은 행에 대해 하위 쿼리를 실행하지 않고 업데이트 할 원시 inner join을 제공합니다. 그것은 많이 빠른 경향이 있습니다.

update table1 t1 
inner join table2 t2 on 
    t1.usr_id = t2.usr_id 
set t1.user_id = t2.user_id 

usr_id 열에도 색인이 있어야합니다. 그러면 속도가 상당히 빨라질 것입니다.

일부 행이 일치하지 않아 t1.user_id = null으로 설정하려는 경우 inner join 대신 left join을 사용해야합니다. 이미 열이 null 인 경우 t2의 값으로 업데이트하려는 경우 inner join을 사용하는 것이 더 빠릅니다.

나는 후자를 위해 MySQL 구문 이라고 언급해야합니다. 다른 RDBMS의 경우 다른 방법으로 update join을 사용합니다.

+1

이 쿼리는 동일한 결과 (즉, 결석 한 행에'NULL's)를 생성하기 위해 'LEFT JOIN'이 필요합니다. – Quassnoi

+0

와우! 100 행 - 평균 650ms에 대한 쿼리를 테스트했습니다. 두 테이블의 usr_id에 생성 된 인덱스 키 MUL 100 행 평균 7ms! – ed209

+0

@ ed209 : 약간의 변화가 얼마나 큰 영향을 미칠지 놀랍습니다. – Eric

0

:

  1. 그들이 테이블의 유형은 무엇입니까?
  2. 그들에 어떤 색인이 있습니까? table2user_id에 인덱싱 user_id과 처음 두 열로 usr_idtable1 포함 인덱스가 있으면

, 그 나쁜이어야한다.

0

t2.usr_id에 대한 색인이 없습니다.

이 인덱스를 생성하고 쿼리를 다시 실행하거나 @Eric (LEFT JOIN 포함)으로 제안 된 다중 테이블 UPDATE.

MySQL에는 NESTED LOOPS 이외의 다른 JOIN 메서드가 없으므로, UPDATE 구문이 아닌 중요한 인덱스임을 유의하십시오.

그러나 다중 테이블 UPDATE이 더 읽기 쉽습니다.