MySQL 5.1 đến 5.6: hiệu suất lớn


7

Được rồi, đây có thể là ba câu hỏi. Tôi muốn chuyển cơ sở dữ liệu MySQL 5.1 hiện tại của mình bằng MyISAM sang 5.6 bằng InnoDB vì những gì tôi nghĩ là một loạt các lý do rõ ràng - và thậm chí có thể tốt -.

Đây là trên Amazon RDS, vì vậy lộ trình nâng cấp của tôi bị giới hạn trong việc bán phá giá và tạo lại cơ sở dữ liệu.

Tôi sẽ vui vẻ thú nhận rằng tôi không phải là một DBA tinh vi.

Vấn đề 1: Wow là chậm!

Mất khoảng 15 phút để mysqldumpcác hàng 160 triệu lẻ của chúng tôi. (Hiển thị bảng vv đang đến, giữ ngựa của bạn.)

Phải mất khoảng 50 giờ để tải nó vào một phiên bản mysql 5.6 với công cụ sed-script-ed thủ công cho InnoDB.

Vấn đề 2: Đâu là tôi hàng ?

select count(*) from node;trên DB hiện tại cho khoảng 162 triệu. Trên 5.6, nó cho khoảng 93 triệu. Tải có vẻ thành công, mặc dù tôi không thể chứng minh điều đó; ít nhất, không có thông báo lỗi sau khi tải kết thúc.

Nếu nó không thành công, điều đó thực sự chậm.

Vấn đề 3: WOW là chậm!

Vì vậy, select count(*) from node;hoàn thành trong khoảng thời gian không có gì cả - trong khoảng từ 0,00 đến 0,03 giây theo kết quả truy vấn - vào ngày 5.1. Vào ngày 5.6 với InnoDB, phải mất hơn một phút. Giải thích cho thấy rõ điều này là do sự khác biệt trong cách tối ưu hóa truy vấn - nhưng không rõ tại sao nó lại khác.

Bảng và giải thích

MySQL 5.1

mysql> show create table node\G
*************************** 1. row ***************************
       Table: node
Create Table: CREATE TABLE `node` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `graph` varchar(100) CHARACTER SET latin1 DEFAULT NULL,
  `subject` varchar(200) NOT NULL,
  `predicate` varchar(200) NOT NULL,
  `object` mediumtext NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `nodeindex` (`graph`(20),`subject`(100),`predicate`(100),`object`(100)),
  KEY `ix_node_subject` (`subject`),
  KEY `ix_node_graph` (`graph`),
  KEY `ix_node_object` (`object`(255)),
  KEY `ix_node_predicate` (`predicate`),
  KEY `node_po` (`predicate`,`object`(130)),
  KEY `node_so` (`subject`,`object`(130)),
  KEY `node_sp` (`subject`,`predicate`(130)),
  FULLTEXT KEY `node_search` (`object`)
) ENGINE=MyISAM AUTO_INCREMENT=550671861 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> select count(id) from node;
+-----------+
| count(id) |
+-----------+
| 163426434 |
+-----------+
1 row in set (0.00 sec)


mysql> explain select count(id) from node;
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows | Extra                        |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
|  1 | SIMPLE      | NULL  | NULL | NULL          | NULL | NULL    | NULL | NULL | Select tables optimized away |
+----+-------------+-------+------+---------------+------+---------+------+------+------------------------------+
1 row in set (0.00 sec)

MySQL 5.6

mysql> show create table node\G
*************************** 1. row ***************************
       Table: node
Create Table: CREATE TABLE `node` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `graph` varchar(100) CHARACTER SET latin1 DEFAULT NULL,
  `subject` varchar(200) NOT NULL,
  `predicate` varchar(200) NOT NULL,
  `object` mediumtext NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `nodeindex` (`graph`(20),`subject`(100),`predicate`(100),`object`(100)),
  KEY `ix_node_subject` (`subject`),
  KEY `ix_node_graph` (`graph`),
  KEY `ix_node_object` (`object`(255)),
  KEY `ix_node_predicate` (`predicate`),
  KEY `node_po` (`predicate`,`object`(130)),
  KEY `node_so` (`subject`,`object`(130)),
  KEY `node_sp` (`subject`,`predicate`(130)),
  FULLTEXT KEY `node_search` (`object`)
) ENGINE=InnoDB AUTO_INCREMENT=481239575 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

`` `

mysql> explain select count(id) from node;
+----+-------------+-------+-------+---------------+---------------+---------+------+----------+-------------+
| id | select_type | table | type  | possible_keys | key           | key_len | ref  | rows     | Extra       |
+----+-------------+-------+-------+---------------+---------------+---------+------+----------+-------------+
|  1 | SIMPLE      | node  | index | NULL          | ix_node_graph | 103     | NULL | 79671827 | Using index |
+----+-------------+-------+-------+---------------+---------------+---------+------+----------+-------------+
1 row in set (0.00 sec)

Câu trả lời:


8

Các vấn đề của bạn không có gì do phiên bản của MySQL. Nó phải làm với Storage Engine.

Trả lời VẤN ĐỀ # 1: Wow thật là chậm!

Chạy mysqldump chỉ chạm vào dữ liệu từ .MYDtệp của bảng MyISAM. Do đó, tôi không tìm thấy bất cứ điều gì đáng ngạc nhiên về việc bán 163 triệu hàng trong 15 phút.

Tải dữ liệu vào Amazon RDS mất 50 giờ cũng không gây sốc cho tôi. Tại sao ?

Bất kể mô hình máy chủ nào bạn chọn cho MySQL RDS, nhật ký giao dịch InnoDB (ib_logfile0, ib_logfile1) luôn là 128M và không được phép thay đổi, ngay cả RDS CLI . Tôi đã viết về điều này trước đây: Cơ sở dữ liệu địa phương so với Amazon RDS

Tất cả ghi vào InnoDB đều được ghi vào Bộ đệm ghi đôi> Bạn nên tắt nó trước khi tải: Xem bài đăng của tôi Khả năng để tăng tốc các BÀI TẬP và CẬP NHẬT của InnoDB

Từng khối hàng từ mỗi INSERT được xử lý như một giao dịch với nội dung được ghi thông qua bộ đệm ghi kép của ibdata1 và nhật ký giao dịch. Như vậy, sự chậm chạp.

Trả lời VẤN ĐỀ # 2: Hàng của tôi ở đâu?

Nhìn vào nodeindex. Tôi có thể thấy nó là một chỉ số tiền tố.

Theo Tài liệu MySQL trênCREATE INDEX :

Hỗ trợ tiền tố và độ dài của tiền tố (nơi được hỗ trợ) phụ thuộc vào công cụ lưu trữ. Ví dụ: tiền tố có thể dài tới 1000 byte cho các bảng MyISAM và 767 byte cho các bảng InnoDB.

Tôi gần như có thể đảm bảo rằng bất kỳ hàng nào có độ dài graph,subject,predicate,objectvượt quá 767 không được đưa vào bảng InnoDB.

Trả lời VẤN ĐỀ # 3: Wow thật là chậm!

Điều này là do Công cụ lưu trữ.

Khi bạn chạy select count(id) from node;với MyISAM, MyISAM gian lận và chạm vào .MYDtiêu đề để lấy số hàng. Do đó, thời gian chạy để lấy số hàng không phải là hàm của số hàng thực tế. Đó là cách Trình tối ưu hóa truy vấn MySQL tối ưu hóa tất cả các cơ chế tiêu chuẩn và cung cấp cho bạn số lượng hàng.

Khi nói đến InnoDB, vì nó không lưu số đếm hàng, một bảng phải được quét hoàn toàn mỗi lần: Xem bài đăng của tôi Tại sao InnoDB không lưu trữ số hàng?

GỢI Ý

Tôi sẽ không nhập nó dưới dạng InnoDB. Tôi sẽ nhập là MyISAM đầu tiên. Sau đó, chuyển đổi tất cả các bảng MyISAM của bạn sang InnoDB. Trước khi chuyển đổi nó, bạn có thể phải thay đổi nodeindexhoặc loại bỏ hoàn toàn. Nếu không, bạn sẽ mất các hàng khi chuyển đổi.

Xem bài đăng của tôi Đầu tiên: nâng cấp phiên bản mysql hoặc chuyển đổi công cụ lưu trữ? để biết thêm thông tin.


Cảm ơn. Hừm. Tôi đã lên kế hoạch làm lại DB trong một thời gian, thay thế VARCHARS khổng lồ - vốn chỉ có trong vùng lân cận 50 giá trị riêng biệt - với một chỉ mục sang một bảng khác và chuyển FULLTEXT sang một bảng riêng. Nghe có vẻ như tôi sẽ không nhận được nhiều từ InnoDB mà không cắn viên đạn vào đó.
Charlie Martin
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.