2010-09-30 25 views
7

Tôi đang cố gắng hiểu rõ hơn về tốc độ chèn và các mẫu hiệu suất trong mysql cho một sản phẩm tùy chỉnh. Tôi có hai bảng mà tôi tiếp tục thêm hàng mới. Hai bảng được định nghĩa như sau:Tốc độ chèn chậm khi bảng phát triển trong mysql

CREATE TABLE events (
added_id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
id BINARY(16) NOT NULL, 
body MEDIUMBLOB, 
UNIQUE KEY (id)) ENGINE InnoDB; 

CREATE TABLE index_fpid (
fpid VARCHAR(255) NOT NULL, 
event_id BINARY(16) NOT NULL UNIQUE, 
PRIMARY KEY (fpid, event_id)) ENGINE InnoDB; 

Và tôi tiếp tục chèn các đối tượng mới vào cả hai bảng (cho mỗi đối tượng mới, tôi chèn thông tin liên quan vào cả hai bảng trong một giao dịch). Lúc đầu, tôi nhận được khoảng 600 insertions/sec, nhưng sau ~ 30000 hàng, tôi nhận được một sự suy giảm đáng kể (khoảng 200 insertions/sec), và sau đó chậm hơn, nhưng vẫn đáng chú ý chậm lại.

Tôi có thể thấy rằng khi bảng phát triển, số chờ IO ngày càng cao. Suy nghĩ đầu tiên của tôi là bộ nhớ được thực hiện bởi chỉ mục, nhưng những người được thực hiện trên một máy ảo có 768 Mb, và được dành riêng cho nhiệm vụ này một mình (2/3 bộ nhớ không sử dụng). Ngoài ra, tôi có một thời gian khó nhìn thấy 30000 hàng dùng quá nhiều bộ nhớ, thậm chí nhiều hơn như vậy chỉ là các chỉ mục (toàn bộ dữ liệu mysql dir < 100 Mb anyway). Để xác nhận điều này, tôi đã cấp rất ít bộ nhớ cho VM (64 Mb) và mô hình chậm lại gần như giống hệt nhau (nghĩa là sự chậm lại xuất hiện sau cùng số lần chèn), vì vậy tôi nghi ngờ một số vấn đề về cấu hình, đặc biệt là vì tôi tương đối mới cơ sở dữ liệu.

Các mô hình trông như sau: alt text

Tôi có một kịch bản python khép kín mà tái tạo vấn đề, mà tôi có thể làm cho có sẵn nếu đó là hữu ích.

Cấu hình:

  • Ubuntu 10.04, 32 bit chạy trên KVM, 760 Mb phân bổ cho nó.
  • Mysql 5.1, ra khỏi cấu hình hộp với các tập tin riêng biệt cho các bảng

[EDIT]

Cảm ơn bạn rất nhiều để Eric Holmberg, ông đóng đinh nó. Dưới đây là các biểu đồ sau khi sửa innodb_buffer_pool_size thành giá trị hợp lý: alt text

+0

Sự cố khả năng ghi vào ổ đĩa, ảo hoặc cách khác. –

+0

Tôi không chắc tôi hiểu ý của bạn là gì: Tôi hiểu rằng phải mất thời gian để ghi vào đĩa, nhưng điều đó không giải thích được sự chậm lại khi bảng phát triển. –

Trả lời

8

Chỉnh sửa tệp /etc/mysql/my.cnf của bạn và đảm bảo bạn phân bổ đủ bộ nhớ cho vùng đệm bộ đệm InnoDB. Nếu đây là một máy chủ chuyên dụng, bạn có thể sử dụng tới 80% bộ nhớ hệ thống của bạn.

# Provide a buffer pool for InnoDB - up to 80% of memory for a dedicated database server 
innodb_buffer_pool_size=614M 

Các khóa chính là B Cây để chèn sẽ luôn mất thời gian O (logN) và khi bạn hết bộ nhớ cache, chúng sẽ bắt đầu hoán đổi như điên. Khi điều này xảy ra, có thể bạn sẽ muốn phân vùng dữ liệu để giữ cho tốc độ chèn của bạn tăng lên. Xem http://dev.mysql.com/doc/refman/5.1/en/partitioning.html để biết thêm thông tin về phân vùng.

Chúc may mắn!

+0

Đó là nó, cảm ơn bạn rất nhiều. Tôi sẽ cập nhật các đồ thị để cho thấy sự khác biệt, nó khá ấn tượng. Cảm ơn cho mẹo phân vùng: Tôi đã xem xét phân vùng đã có, nhưng tôi không muốn đến đó mà không hiểu vấn đề này trước. –

+2

Cảm ơn bạn đã đi thêm dặm để cập nhật biểu đồ - tập thứ hai trông tuyệt vời! –

1

Chỉ mục của bạn có thể chỉ cần được phân tích và tối ưu hóa khi chèn, chúng dần dần bị mất đi khi bạn đi. Các tùy chọn khác của khóa học là để vô hiệu hóa chỉ mục hoàn toàn khi bạn đang chèn và xây dựng lại chúng sau này sẽ cung cấp cho hiệu suất nhất quán hơn.

Great link about insert speed.

ANALYZE. OPTIMIZE

+0

Chỉ có hai chỉ mục - khóa chính và một ràng buộc duy nhất. Cả hai đều thực thi các giá trị duy nhất. Trừ khi có xóa, không có gì để duy trì. –

+0

Tôi không nghĩ rằng tôi có thể vô hiệu hóa chỉ mục (trong ứng dụng của tôi, tôi cần phải chèn sẵn ngay khi chúng được viết và chèn vào "thời gian thực", nó không phải là xử lý theo lô). –

+0

Tôi tin tưởng bạn OMG, nếu bạn nói đó là trường hợp tôi háo hức chờ đợi câu trả lời của bạn để tôi có thể học hỏi. –

0

Xác minh rằng chèn không vi phạm ràng buộc khóa mất một thời gian và thời gian đó tăng lên khi bảng lớn hơn. Nếu bạn quan tâm đến hiệu suất phẳng, sử dụng LOAD DATA INFILE sẽ cải thiện tốc độ chèn của bạn đáng kể.

+0

Tôi dự kiến ​​chèn chậm khi bảng phát triển (vì chi phí nhật ký (N) của các chỉ mục cập nhật). Nhưng sự chậm lại ở đây là do IO tăng lên, nếu tôi tin rằng iowait%, và đó là điều bất ngờ (vì tôi có một tập dữ liệu đủ nhỏ để vừa hoàn toàn trong bộ nhớ). Ngoài ra, đồ thị của tôi không thể hiện một bản ghi (N) chậm lại. –

+0

Hơi hiếm khi toàn bộ tập dữ liệu của bạn sẽ khớp với bộ nhớ, nhưng tôi rất vui vì sự cố của bạn đã được giải quyết. 'LOAD DATA INFILE' sẽ vẫn hiển thị cho bạn các cải tiến hiệu suất cao hơn nếu yêu cầu của bạn là như vậy. –

Các vấn đề liên quan