2013-12-17 5 views
0

현재 8 백만 행 이상의 MySQL Db가있는 프로젝트를 진행하고 있습니다. 일부 쿼리를 테스트하기 위해 일부가 제공되었습니다. 그 중 약 20 개의 열이 있는데 그 중 5 개가 나에게 유용합니다. 즉 : First_Name, Last_Name, Address_Line1, Address_Line2, Address_Line3, RefundID하위 쿼리로 업데이트가 완료되지 않음

각 행에 대해 고유하지만 임의의 RefundID을 작성해야하는데 이는 문제가되지 않습니다. 문제는 First_Name, Last_Name, Address_Line1, Address_Line2, Address_Line3이 같은 행에 대해 과 동일한RefundID을 생성하는 것입니다.

이것은 큰 행 수가 많은 MySQL과 관련한 첫 번째 실제 작업입니다. 지금까지 나는이 쿼리를 만들었습니다

-- Creating Teporary Table -- 
CREATE temporary table tempT (SELECT tt.First_Name, count(tt.Address_Line1) as 
a1, count(tt.Address_Line2) as a2, count(tt.Address_Line3) as a3, tt.RefundID 
FROM `tempTable` tt GROUP BY First_Name HAVING a1 >= 2 AND a2 >= 2 AND a3 >= 2); 
-- Updating Rows with First_Name from tempT -- 
UPDATE `tempTable` SET RefundID = FLOOR(RAND()*POW(10,11)) 
WHERE First_Name IN (SELECT First_Name FROM tempT WHERE First_Name is not NULL); 

이 업데이트 쿼리가 실행에 계속 없지만 결코 끝, tempT 개 이상의 30K 행이 있습니다. 이 쿼리는 800K 개 이상의 행이있는 기본 DB에서 실행됩니다.

누군가 나를 도와 줄 수 있습니까?

감사

답변

1

용액 ....

가 임의의 값을 사용하지 마십시오 - 해시를 사용

UPDATE yourtable 
SET refundid = MD5('some static salt', First_Name 
    , Last_Name, Address_Line1, Address_Line2, Address_Line3) 

문제는이다 refundId에 정수 값을 사용하는 경우 충돌이 발생할 가능성이 있습니다 (힌트 CONV (SUBSTR (MD5 (...), 1,16), 16,10)하여 서명 된 BIGINT를 얻을 수 있습니다. 그러나 당신은 그 분야의 유형이 무엇인지에 대해 말하지 않았으며, '독특한'요건이 얼마나 엄격한 지에 대해서도 말하지 않았습니다. 하나의 패스로 업데이트를 수행합니다.

밀집된 숫자의 연속을 만드는 또 다른 방법은 원본 테이블의 고유 값과 임의 값을 사용하여 임시 테이블을 만드는 것입니다. 임의의 값을 기준으로 순서와 일정하게 증가하는 refundId 설정 - 다음 룩업 테이블로 사용하거나 원래의 테이블을 업데이트 :

SELECT DISTINCT First_Name 
    , Last_Name, Address_Line1, Address_Line2, Address_Line3 
INTO temptable 
FROM yourtable; 

set @counter=-1; 

UPDATE temptable t SET t,refundId=(@counter:[email protected] + 1) 
ORDER BY r.randomvalue; 

이 다른 솔루션도있다 - 그러나보다 효율적인 것들의 복사본을 여러 개 가지고에 의존 데이터 및/또는 절차 언어 사용.

+0

안녕하세요. 회신 해 주셔서 감사합니다. 환불 ID는 9-12 자의 고유 한 값이어야합니다. MD5는 32 자리입니다. (나쁜 숫자 메모리). 나는'First_Name, Last_Name, Address_Line1, Address_Line2, Address_Line3'이 같은 모든 행에 동일한 ID를 부여해야합니다. 감사합니다 –

+0

네, 그 사건일지도 모르고 분명히 위의 내 대답에 이것을 해결했다. – symcbean

0

다음 사용해보십시오 :

MySQL의에서
UPDATE `tempTable` x SET RefundID = FLOOR(RAND()*POW(10,11)) 
WHERE exists (SELECT 1 FROM tempT y WHERE First_Name is not NULL and x.First_Name=y.First_Name); 
+0

지금 당장 귀하의 질문을 실행하고 있는데, 이것이 4GB 램이 장착 된 i7에 얼마나 걸릴 것이라고 생각하십니까? 내 PC 사양. I.E 약 30K 행. –

+0

비록 나라면 100 개의 결과, 1000, 10000 등으로 시도해 볼 것이지만 추측을 시도하지 않을 것입니다. 또한 그것이 무엇을하고 있는지를 설명하기 위해 설명 할 수 있습니다. 너무 오래 걸립니다. 존재하는 버전은 더 빨라야합니다. –

+0

나는 그것이 6 분 동안 뛰게하고 결코 끝나지 않았다. 나는 먼저 그것을 10 열로 시도 할 것이다. 감사합니다 –

0

, 종종 하위 쿼리를 사용하여 where 절을 통해 필터링하는 것보다 updatejoin를 사용하는 것이 더 효율적입니다. 다음은 더 잘 수행 할 수 있습니다 나에게 분명한 것 같다

UPDATE `tempTable` join 
     (SELECT distinct First_Name 
     FROM tempT 
     WHERE First_Name is not NULL 
     ) fn 
     on temptable.First_Name = fn.First_Name 
    SET RefundID = FLOOR(RAND()*POW(10,11));