4 억 개의 행을 가진 비표준 데이터베이스가 있습니다. 모든 반복 데이터를 새 정규화 데이터베이스로 이동 했으므로 ID로 나타낼 수 있습니다.거대한 비정규 화 된 mysql 데이터베이스 부분 2를 재구성하십시오.
이제 모든 데이터 항목을 이동하고 ID가있는 항목으로 변환해야합니다.
문제는 400m 행을 사용하면 다소 시간이 걸릴 것이므로 최적화하는 데 도움이 필요합니다.
이 쿼리는 행 당 0.4 초 소요, 그래서 몇 개월이 걸릴 것입니다 : 걸리는 것이이 방법을 좀 더 PHP를 사용하는 경우
INSERT IGNORE INTO normalized.entry (insDate, `date`, project, keyword, url, position, competition, serachEngine)
SELECT
CURDATE() as insDate
, d.id as dateId
, p.id as projectId
, k.id as keywordId
, z.id AS urlId
, old.position
, old.competition
, s.id as searchEngineId
FROM unnormalized.bigtable old
INNER JOIN normalized.`date` d ON old.insDate = d.`date`
INNER JOIN normalized.project p ON old.awrProject = p.project
INNER JOIN normalized.searchEngine s ON old.searchEngine = s.searchEngine
INNER JOIN normalized.keyword k ON old.keyword = k.keyword
INNER JOIN normalized.urlHash z ON old.url = z.url
WHERE old.id >= ".$start." AND old.id <= ".$stop."";
두 querys로 분할에만 0.07sec 항목 당하지만 여전히 걸립니다 또한 달의 :
$q = "SELECT tmp.id
, d.id as dateId
, p.id as projectId
, k.id as keywordId
, tmp.position
, tmp.competition
, s.id as searchEngineId
, tmp.url
, z.id AS urlId
FROM unnormalized.bigtable tmp
INNER JOIN normalized.`date` d ON tmp.insDate = d.`date`
INNER JOIN normalized.project p ON tmp.awrProject = p.project
INNER JOIN normalized.searchEngine s ON tmp.searchEngine = s.searchEngine
INNER JOIN normalized.keyword k ON tmp.keyword = k.keyword
INNER JOIN normalized.urlHash z ON tmp.url = z.url
WHERE tmp.id > ".$start." AND tmp.id < ".$stop."";
// echo $q;
$result = mysql_query($q, $local);
if (mysql_num_rows($result) > 0) {
while ($row = mysql_fetch_array($result)) {
$q = "SELECT id FROM normalized.url WHERE url = '".$row["url"]."'";
$resultUrl = mysql_query($q, $local);
$rowUrl = mysql_fetch_array($resultUrl);
$q = "INSERT IGNORE normalized.entry (insDate, `date`, project, keyword, url, position, competition, serachEngine) VALUES (NOW(), '".$row["dateId"]."', '".$row["projectId"]."', '".$row["keywordId"]."', '".$rowUrl["id"]."', '".$row["position"]."', '".$row["competition"]."', '".$row["searchEngineId"]."')";
나는 그것이 반년 복용하지 않고이 데이터거야 포트 얼마나 몰라! /모두 도움이 필요합니다.
사양 : RDS 아마존 서버에서 InnoDB를 사용하고 있습니다.
편집 :
ID, SELECT_TYPE, 테이블, 유형,이 possible_keys, 키,있는 key_len, 심판, 행 추가 1, SIMPLE, P, 인덱스, NULL, 프로젝트 이름, 42 : 첫 번째 쿼리의 SELECT를 EXPLAIN , NULL, 1346, "인덱스 사용" 1, SIMPLE, s, 인덱스, NULL, searchEngine, 42, NULL, 2336, "인덱스 사용, 조인 버퍼 사용" 1, SIMPLE, k, 인덱스, NULL, 키워드, 42 , NULL, 128567, "인덱스 사용, 조인 버퍼 사용" 1, SIMPLE, tmp, ref, "keyword_url_insDate, keyword, searchEngine, url, awrProject", keyword_url_insDate, 767, func, 115, "" 1, SIMPLE , d, eq_ref, 날짜, 날짜, 3, intradb.tmp.insDate, 1, "Where 사용, 색인 사용" 1, SIMPLE, z, ref, url, url, 767, bbointra db.tmp.(표를 rankingUrls201001
( id
INT (11) NOT NULL AUTO_INCREMENT, insDate
날짜 NOT NULL, keyword
VARCHAR 만들기 ', 255
'rankingUrls201001 ': "인덱스를 사용하여'URL, 1,
SHOW CREATE TABLE을)) utf8_swedish_ci가 NULL NOT COLLATE) NULL NOT utf8_swedish_ci 대조) competition
VARCHAR를 NULL NOT position
INT (11 url
VARCHAR (255 utf8_swedish_ci NOT NULL, searchEngine
VARCHAR (25 부씩 (20) COLLATE utf8_swedish_ci은 NOT NULL이 awrProject
VARCHAR (200) utf8_swedish_ci에게 NULL NOT 부씩 server
VARCHAR (20) utf8_swedish_ci에게 NULL NOT 부씩 rank
VARCHAR (40) utf8_swedish_ci에게 NULL NOT 부씩 PRIMARY KEY (id
) keyword_url_insDate
KEY (keyword
, url
, insDate
) KEY keyword
(keyword
) KEY searchEngine
(searchEngine
) KEY url
(url
) KEY awrProject
(awrProject
) ) ENGINE = InnoDB AUTO_INCREMENT = 2266575 DEFAULT CHARSET = utf8 COLLATE = utf8_swedish_ci '
테이블의 스키마는 무엇입니까? ('SHOW CREATE TABLE your_table'의 출력) – Jocelyn
'EXPLAIN your_select_query' (질문에 첫 번째 INSERT 쿼리에서 사용 된 SELECT 쿼리)의 결과는 무엇입니까? – Jocelyn
게시물 하단에 EXPLAIN 출력을 추가했습니다. –