2011-08-27 8 views
9

Tôi có một bảng MySQL lớn (~ 10 Triệu hàng, 6.5G) Tôi sử dụng để đọc & viết. Nó là MyISAM, và tôi nhận được rất nhiều ổ khóa do khóa của MyISAM trên tất cả các bảng viết.InnoDB vs. MyISAM chèn thời gian truy vấn

Tôi quyết định thử và chuyển sang InnoDB được đề xuất cho các bảng đọc/ghi và chỉ khóa các hàng cụ thể trên ghi.

Sau khi chuyển đổi, tôi đã thử nghiệm các câu lệnh chèn, và hóa ra mất hơn 15 lần (từ 0,1 giây đến 1,5 giây) trong bảng InnoDB so với bảng MyISAM. Tại sao vậy?

Tôi chưa định cấu hình bất kỳ thứ gì cho InnoDB và lập kế hoạch thêm phân vùng, nhưng con số này vẫn là điều bất ngờ đối với tôi. Tất nhiên các bảng đều giống nhau, cùng chỉ số vv

Bổ sung thông tin theo yêu cầu:

2 chỉ số. primary là data_id của kiểu Big INT, và không phải là user_id duy nhất của kiểu varchar (255).

Chèn là ~ 150 hàng cùng nhau có cùng user_id.

Kích thước của chỉ số: 200 MB trong MyISAM, 400MB trong InnoDB

+3

Bạn có thể chỉ cho chúng tôi các chỉ mục không? Đó là nguyên nhân có thể gây ra thời gian chèn dài nhất. – wallyk

+0

Tôi có 2 chỉ mục, data_id là khóa chính và user_id không phải là duy nhất. Chèn của tôi là ~ 150 hàng với nhau có cùng user_id (trong đó có một chỉ mục). – normalppl

+0

nhưng nội dung của từng chỉ mục là gì? Nếu có một loạt các đốm màu, thì chắc chắn sẽ khó lập chỉ mục. Nhưng nếu chúng là các số nguyên hoặc các loại tầm thường khác, thì sẽ khó hiểu tại sao hiệu suất lại xấu. – wallyk

Trả lời

5

Một related answer gợi ý rằng thiết lập các biến innodb_flush_log_at_trx_commit-2 là khả năng cải thiện hiệu suất khi tỷ lệ viết để đọc là tương đối cao. Xem the documentation để biết thêm.

+0

Tôi hiện chỉ đang thử nghiệm. vì vậy không có lần đọc nào, chỉ cần chèn một hàng 150 hàng, muốn tìm ra hàng đầu tiên. – normalppl

+1

Điều này tạo nên sự khác biệt to lớn đối với tôi. Chèn 7500 hàng mà không thay đổi 'innodb_flush_log_at_trx_commit' mất 5 phút. Thay đổi nó thành 0 hoặc 2 giảm cùng INSERT xuống còn 3 giây. – qris

3

Hãy nhớ cách InnoDB xử lý các khóa có thể gây rắc rối. Vì mọi thứ được lưu trữ trên đĩa theo thứ tự khóa chính có khóa chính không tự động tăng có thể khiến nhiều bảng được di chuyển trên đĩa với bất kỳ chèn nào (tôi đã gặp sự cố này khi tôi có bảng tổng hợp và được sử dụng các id được kết hợp làm khóa chính). Di chuyển dữ liệu trên đĩa chậm.

Ngoài ra kích thước chỉ mục có thể lớn hơn nhiều với InnoDB vì mỗi chỉ mục cũng chứa khóa chính. Kiểm tra để chắc chắn rằng bạn không chạy vào bất kỳ giới hạn bộ nhớ nào.

+0

tôi đã không mong đợi nó được nhanh hơn, tôi nhận ra nó phải giúp đỡ với nhiều đọc \ viết. Nhưng nếu chèn cơ bản tôi thường thực hiện mất 15 lần nhiều hơn (từ 0,1 giây đến 1,5 giây) mà âm thanh như một cái gì đó không phải là ok, không? – normalppl

+1

Vâng, xin lỗi, đã đọc 15% không phải 15x - có thể có một số vấn đề – jisaacstone

4

Tôi nghĩ, InnoDB triển khai ACID thực, và thực hiện rất nhiều fsync() s để lưu dữ liệu. Và MyISAM không phải là một ACID thực và ít fsync() s.

There are recomendations to kill fsync khi bạn cần phải tải dữ liệu rất lớn trong

If you want to load data into InnoDB quickly: 
* use as large an InnoDB buffer cache as possible 
* make the InnoDB log files as large as possible 
* minimize the number of unique indexes on your tables 
* disable all calls to fsync from InnoDB. You have to hack the code to 
get this, or look at the Google patch. Of course, you only want to run 
in this mode when loading the table. 

And lists says:

MyISAM luôn chạy ở chế độ 'nosync', có nghĩa là, nó không bao giờ gọi fsync() để tuôn các tệp đến đĩa.

nosync của InnoDB hữu ích khi thử nghiệm nếu một số hệ điều hành/máy tính cực kỳ chậm trong fsync(). Nhưng nó không nên được sử dụng trong một hệ thống sản xuất.

Thông điệp tương tự nói, rằng InnoDB đôi khi sử dụng một phương pháp đồng bộ:

Sau đó InnoDB sử dụng fsync() để tuôn cả các dữ liệu và file log.Nếu O_DSYNC là được chỉ định, InnoDB sử dụng O_SYNC để mở và xóa các tệp nhật ký, nhưng sử dụng fsync() để xóa các tệp dữ liệu. Nếu O_DIRECT được chỉ định (có sẵn trên một số phiên bản Linux bắt đầu từ MySQL-4.0.14), InnoDB sử dụng O_DIRECT để mở các tệp dữ liệu và sử dụng fsync() để xóa cả dữ liệu và tệp nhật ký. Lưu ý rằng InnoDB không sử dụng fdatasync() hoặc O_DSYNC vì đã có sự cố với chúng về nhiều hương vị Unix.

2

Đầu tiên, kiểm tra của bạn không hợp lệ, vì việc tăng tốc độ khóa cấp hàng với khóa cấp bảng đến khi bạn có đồng thời! Chỉ với 1 sợi chèn, bạn có 1 khóa/mở khóa cho mỗi lần chèn trong cả hai trường hợp, và chèn không chờ đợi các khóa cấp bảng được phát hành.

Giây, như được nêu trong JIStone, khóa chính không tuần tự là sát thủ hiệu suất cho chèn, khi kích thước bảng lớn hơn vùng đệm.

Thứ ba, kích thước vùng đệm là một trong những cài đặt quan trọng nhất trong InnoDB. Làm cho nó như lare càng tốt (đề nghị thiết lập là 80% ot RAM có sẵn).

Tiếp theo, như đã nêu trong @wallyk, innodb_flush_log_at_trx_commit có vai trò quan trọng đối với tốc độ hoạt động I/O.

Tiếp theo, innodb_log_file_size và innodb_buffer_file_size rất quan trọng.

Tiếp theo, hãy nhớ rằng vì bạn có 2 chỉ mục duy nhất, trước khi InnoDB có thể chèn hàng, nó phải kiểm tra sự tồn tại của giá trị trong chỉ mục và chỉ mục của bạn lớn.

Nếu không có thông tin chi tiết về bảng và chỉ mục, tôi không thể cung cấp thêm lời khuyên cho bạn, nhưng xin lưu ý rằng không có công cụ lưu trữ nào là thuốc chữa bách bệnh, và mặc dù thường bạn có thể đạt được rất nhiều tốc độ thêm chỉ mục hoặc tinh chỉnh một biến, trong các hệ thống có quy mô lớn, mọi thứ phức tạp hơn điều này. Nhưng, như tôi đã nói, bạn không nên so sánh tốc độ chèn nguyên trong thử nghiệm riêng rẽ, bạn phải thực hiện thử nghiệm của mình gần với ứng dụng thực nhất có thể.

cập nhật: thêm một mũi Trong cả hai MyISAM và InnoDB, đa chèn (insert into .... giá trị (...), (...), (...)) là nhanh hơn. Ngoài ra, trong InnoDB, bạn có thể biến các giao dịch của mình thành giao dịch, vô hiệu hóa việc cập nhật các chỉ mục không độc nhất trước khi giao dịch hoàn thành, và nó cũng nhanh hơn (nhưng không thực hiện các giao dịch lớn, vì điều này thực sự sẽ làm chậm quá trình sử dụng) cách hoạt động của phiên bản hàng).