대부분의 테이블에 InnoDB 스토리지 엔진과 함께 MySQL 5.6 사용. InnoDB 버퍼 풀 크기는 15GB이고 Innodb DB + 인덱스는 약 10GB입니다. 서버에 32GB RAM이 있으며 Cent OS 7 x64를 실행 중입니다.
나는 약 천만 + 레코드를 포함하는 하나의 큰 테이블을 가지고 있습니다.
24 시간마다 원격 서버에서 업데이트 된 덤프 파일을 얻습니다. 파일은 csv 형식입니다. 해당 형식을 제어 할 수 없습니다. 파일 크기는 ~ 750MB입니다. MyISAM 테이블에 행마다 데이터를 삽입하려고 시도했지만 35 분이 걸렸습니다.
파일에서 10-12 행 중 한 줄에 3 개의 값만 가져 와서 데이터베이스에서 업데이트해야합니다.
이와 같은 것을 달성하는 가장 좋은 방법은 무엇입니까?
나는 이것을 매일해야한다.
현재 흐름은 다음과 같습니다.
- mysqli_begin_transaction
- 라인별로 덤프 파일 읽기
- 각 레코드를 한 줄씩 업데이트하십시오.
- mysqli_commit
위의 작업 을 완료하는 데 약 30-40 분이 걸리며이 작업 을 수행하는 동안 다른 업데이트가 진행 중입니다.
잠금 대기 시간 초과를 초과했습니다. 거래를 다시 시작하십시오
업데이트 1
사용하여 새 테이블에 데이터로드 LOAD DATA LOCAL INFILE
. MyISAM에서는 38.93 sec
InnoDB에서 7 분 5.21 초가 걸렸습니다. 그런 다음 :
UPDATE table1 t1, table2 t2
SET
t1.field1 = t2.field1,
t1.field2 = t2.field2,
t1.field3 = t2.field3
WHERE t1.field10 = t2.field10
Query OK, 434914 rows affected (22 hours 14 min 47.55 sec)
업데이트 2
조인 쿼리와 동일한 업데이트
UPDATE table1 a JOIN table2 b
ON a.field1 = b.field1
SET
a.field2 = b.field2,
a.field3 = b.field3,
a.field4 = b.field4
(14 hours 56 min 46.85 sec)
의견의 질문에 대한 설명 :
- 테이블에있는 행의 약 6 %가 파일에 의해 업데이트되지만 때로는 25 %까지 될 수 있습니다.
- 업데이트되는 필드에 색인이 있습니다. 테이블에는 12 개의 인덱스가 있으며 8 개의 인덱스에는 업데이트 필드가 포함됩니다.
- 한 트랜잭션에서 업데이트를 수행 할 필요 는 없습니다 . 시간이 걸리지 만 24 시간을 넘지 않아야합니다. 나중에이 테이블에 의존하는 스핑크스 인덱스를 업데이트해야하기 때문에 전체 테이블을 잠그지 않고 1 시간 안에 완료하려고합니다. 데이터베이스가 다른 작업에 사용 가능한 경우 단계가 더 오래 걸리는 것은 중요하지 않습니다.
- 전처리 단계에서 CSV 형식을 수정할 수 있습니다. 중요한 것은 빠른 업데이트와 잠금이없는 것입니다.
- 표 2는 MyISAM이다. 데이터로드 파일을 사용하여 csv 파일에서 새로 작성된 테이블입니다. MYI 파일 크기는 452 MB입니다. 표 2는 field1 열에서 색인화됩니다.
- MyISAM 테이블의 MYD는 663MB입니다.
업데이트 3 :
다음은 두 테이블에 대한 자세한 내용입니다.
CREATE TABLE `content` (
`hash` char(40) CHARACTER SET ascii NOT NULL DEFAULT '',
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`og_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`keywords` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
`files_count` smallint(5) unsigned NOT NULL DEFAULT '0',
`more_files` smallint(5) unsigned NOT NULL DEFAULT '0',
`files` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '0',
`category` smallint(3) unsigned NOT NULL DEFAULT '600',
`size` bigint(19) unsigned NOT NULL DEFAULT '0',
`downloaders` int(11) NOT NULL DEFAULT '0',
`completed` int(11) NOT NULL DEFAULT '0',
`uploaders` int(11) NOT NULL DEFAULT '0',
`creation_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`upload_date` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`last_updated` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
`vote_up` int(11) unsigned NOT NULL DEFAULT '0',
`vote_down` int(11) unsigned NOT NULL DEFAULT '0',
`comments_count` int(11) NOT NULL DEFAULT '0',
`imdb` int(8) unsigned NOT NULL DEFAULT '0',
`video_sample` tinyint(1) NOT NULL DEFAULT '0',
`video_quality` tinyint(2) NOT NULL DEFAULT '0',
`audio_lang` varchar(127) CHARACTER SET ascii NOT NULL DEFAULT '',
`subtitle_lang` varchar(127) CHARACTER SET ascii NOT NULL DEFAULT '',
`verified` tinyint(1) unsigned NOT NULL DEFAULT '0',
`uploader` int(11) unsigned NOT NULL DEFAULT '0',
`anonymous` tinyint(1) NOT NULL DEFAULT '0',
`enabled` tinyint(1) unsigned NOT NULL DEFAULT '0',
`tfile_size` int(11) unsigned NOT NULL DEFAULT '0',
`scrape_source` tinyint(1) unsigned NOT NULL DEFAULT '0',
`record_num` int(11) unsigned NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`record_num`),
UNIQUE KEY `hash` (`hash`),
KEY `uploaders` (`uploaders`),
KEY `tfile_size` (`tfile_size`),
KEY `enabled_category_upload_date_verified_` (`enabled`,`category`,`upload_date`,`verified`),
KEY `enabled_upload_date_verified_` (`enabled`,`upload_date`,`verified`),
KEY `enabled_category_verified_` (`enabled`,`category`,`verified`),
KEY `enabled_verified_` (`enabled`,`verified`),
KEY `enabled_uploader_` (`enabled`,`uploader`),
KEY `anonymous_uploader_` (`anonymous`,`uploader`),
KEY `enabled_uploaders_upload_date_` (`enabled`,`uploaders`,`upload_date`),
KEY `enabled_verified_category` (`enabled`,`verified`,`category`),
KEY `verified_enabled_category` (`verified`,`enabled`,`category`)
) ENGINE=InnoDB AUTO_INCREMENT=7551163 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ROW_FORMAT=FIXED
CREATE TABLE `content_csv_dump_temp` (
`hash` char(40) CHARACTER SET ascii NOT NULL DEFAULT '',
`title` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
`category_id` int(11) unsigned NOT NULL DEFAULT '0',
`uploaders` int(11) unsigned NOT NULL DEFAULT '0',
`downloaders` int(11) unsigned NOT NULL DEFAULT '0',
`verified` tinyint(1) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`hash`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci
여기에 content
데이터를 사용하여 테이블 을 업데이트하는 업데이트 쿼리가 있습니다.content_csv_dump_temp
UPDATE content a JOIN content_csv_dump_temp b
ON a.hash = b.hash
SET
a.uploaders = b.uploaders,
a.downloaders = b.downloaders,
a.verified = b.verified
업데이트 4 :
위의 모든 테스트는 테스트 시스템에서 수행되었지만 이제 프로덕션 시스템에서 동일한 테스트를 수행했으며 쿼리 속도가 매우 빠릅니다.
mysql> UPDATE content_test a JOIN content_csv_dump_temp b
-> ON a.hash = b.hash
-> SET
-> a.uploaders = b.uploaders,
-> a.downloaders = b.downloaders,
-> a.verified = b.verified;
Query OK, 2673528 rows affected (7 min 50.42 sec)
Rows matched: 7044818 Changed: 2673528 Warnings: 0
내 실수에 대해 사과드립니다. 각 레코드 업데이트 대신 결합을 사용하는 것이 좋습니다. 이제 rick_james가 제안한 색인을 사용하여 mpre를 개선하려고합니다. 벤치 마킹이 완료되면 업데이트됩니다.
UPDATEs
있습니다. csv 데이터에서 테이블을 업데이트 할 때의 간단한 설명이 무엇인지 정확하게 알려주십시오 . 그런 다음 요구 사항을 충족하는 기술을 고안하는 데 도움을 줄 수 있습니다.
update
업데이트 된 질문을 확인하십시오., 감사
INDEX(field2, field3, field4)
있습니까? 우리에게 보여주세요SHOW CREATE TABLE
.