Sử dụng MySQL 5.6 với công cụ lưu trữ InnoDB cho hầu hết các bảng. Kích thước nhóm bộ đệm của InnoDB là 15 GB và các chỉ số Innodb DB + là khoảng 10 GB. Máy chủ có RAM 32 GB và đang chạy Cent OS 7 x64.
Tôi có một bảng lớn chứa khoảng 10 triệu + hồ sơ.
Tôi nhận được một tệp kết xuất được cập nhật từ một máy chủ từ xa cứ sau 24 giờ. Các tập tin có định dạng csv. Tôi không có quyền kiểm soát định dạng đó. Tệp có dung lượng ~ 750 MB. Tôi đã thử chèn dữ liệu vào một hàng của bảng MyISAM theo hàng và mất 35 phút.
Tôi chỉ cần lấy 3 giá trị trên mỗi dòng trong số 10-12 từ tệp và cập nhật nó trong cơ sở dữ liệu.
Cách tốt nhất để đạt được một cái gì đó như thế này là gì?
Tôi cần phải làm điều này hàng ngày.
Hiện tại Flow là như thế này:
- mysqli_begin_transaction
- Đọc tệp kết xuất theo từng dòng
- Cập nhật từng bản ghi Từng dòng.
- mysqli_commit
Các hoạt động trên mất khoảng 30 đến 40 phút để hoàn thành và trong khi thực hiện việc này, có những cập nhật khác đang diễn ra mang lại cho tôi
Vượt quá thời gian chờ khóa; thử khởi động lại giao dịch
Cập nhật 1
tải dữ liệu trong bảng mới bằng cách sử dụng LOAD DATA LOCAL INFILE
. Trong MyISAM, phải mất 38.93 sec
trong InnoDB, mất 7 phút 5,21 giây. Sau đó, tôi đã làm:
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)
Cập nhật 2
cùng cập nhật với truy vấn tham gia
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)
Làm rõ từ các câu hỏi trong ý kiến:
- Khoảng 6% các hàng trong bảng sẽ được cập nhật bởi tệp, nhưng đôi khi nó có thể lên tới 25%.
- Có các chỉ mục trên các lĩnh vực đang được cập nhật. Có 12 chỉ mục trên bảng và 8 chỉ mục bao gồm các trường cập nhật.
- Không cần thiết phải thực hiện cập nhật trong một giao dịch. Nó có thể mất thời gian nhưng không quá 24 giờ. Tôi đang tìm cách hoàn thành nó trong 1 giờ mà không khóa toàn bộ bảng, vì sau này tôi phải cập nhật chỉ số nhân sư phụ thuộc vào bảng này. Không thành vấn đề nếu các bước mất nhiều thời gian hơn miễn là cơ sở dữ liệu có sẵn cho các tác vụ khác.
- Tôi có thể sửa đổi định dạng csv trong bước tiền xử lý. Điều duy nhất quan trọng là cập nhật nhanh chóng và không khóa.
- Bảng 2 là MyISAM. Đây là bảng mới được tạo từ tệp csv bằng cách sử dụng dữ liệu tải dữ liệu. Kích thước tệp MYI là 452 MB. Bảng 2 được lập chỉ mục trên cột field1.
- MYD của bảng MyISAM là 663MB.
Cập nhật 3:
Dưới đây là chi tiết về cả hai bảng.
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
và đây là truy vấn cập nhật content
bảng cập nhật sử dụng dữ liệu từ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
cập nhật 4:
tất cả các thử nghiệm trên đã được thực hiện trên máy thử nghiệm. Nhưng bây giờ tôi đã thực hiện các thử nghiệm tương tự trên máy sản xuất và các truy vấn rất nhanh.
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
tôi xin lỗi vì lỗi lầm của tôi. Nó tốt hơn để sử dụng tham gia thay vì mỗi bản cập nhật hồ sơ. bây giờ tôi đang cố gắng cải thiện mpre bằng cách sử dụng chỉ mục được đề xuất bởi rick_james, sẽ cập nhật sau khi đánh dấu băng ghế được thực hiện.
UPDATEs
. Vui lòng cho chúng tôi biết chính xác câu lệnh đơn giản trông như thế nào khi cập nhật bảng từ dữ liệu csv. Sau đó, chúng tôi có thể giúp bạn nghĩ ra một kỹ thuật đáp ứng yêu cầu của bạn.
update
, và vui lòng kiểm tra câu hỏi được cập nhật., Cảm ơn
INDEX(field2, field3, field4)
(theo thứ tự nào) không? Xin hãy chỉ cho chúng tôiSHOW CREATE TABLE
.