2009-10-19 42 views
5

Tôi có một chương trình C khai thác một nguồn dữ liệu khổng lồ (20GB văn bản thô) và tạo các tải INSERT để thực thi trên bảng trống đơn giản (4 cột nguyên với 1 khóa chính). Thiết lập dưới dạng bảng MEMORY, toàn bộ tác vụ sẽ hoàn thành sau 8 giờ. Sau khi kết thúc, có khoảng 150 triệu hàng tồn tại trong bảng. Tám giờ là một con số hoàn toàn phù hợp với tôi. Đây là giao dịch một lần.Tạo một bảng MySQL 150M hàng lớn

Sự cố xảy ra khi cố gắng chuyển đổi bảng MEMORY trở lại thành MyISAM để (A) Tôi sẽ giải phóng bộ nhớ cho các quy trình khác và (B) dữ liệu sẽ không bị giết khi tôi khởi động lại máy tính.

ALTER TABLE memtable ENGINE = MyISAM 

Tôi đã cho phép điều này ALTER TABLE truy vấn chạy trong hơn hai ngày và không được thực hiện. Tôi đã giết nó rồi.

Nếu tôi tạo bảng ban đầu là MyISAM, tốc độ ghi có vẻ rất tệ (đặc biệt là do truy vấn yêu cầu sử dụng kỹ thuật ON DUPLICATE KEY UPDATE). Tôi không thể tạm thời tắt các phím. Bảng sẽ trở nên lớn hơn 1000 lần nếu tôi đến và sau đó tôi sẽ phải tái xử lý các phím và về cơ bản chạy một GROUP BY trên 150.000.000.000 hàng. Ừm ... không.

Một trong những ràng buộc chính để nhận ra: Truy vấn INSERT UPDATEs ghi lại nếu khóa chính (băm) tồn tại trong bảng đã có.

Khi bắt đầu một nỗ lực nghiêm chỉnh sử dụng MyISAM, tôi nhận được tốc độ thô 1.250 hàng mỗi giây. Khi chỉ số tăng lên, tôi tưởng tượng tỷ lệ này sẽ tăng hơn nữa.


Tôi có 16GB bộ nhớ được cài đặt trong máy. Cách tốt nhất để tạo ra một bảng lớn cuối cùng kết thúc như một bảng MyISAM được lập chỉ mục trên đĩa là gì?


Làm rõ: Có rất nhiều, rất nhiều thông tin cập nhật diễn ra từ truy vấn (INSERT ... ON DUPLICATE KEY UPDATE val=val+whatever). Đây không phải là, bởi bất kỳ phương tiện, một vấn đề đổ nguyên liệu. Lý do của tôi để thử một bảng MEMORY ở nơi đầu tiên là để tăng tốc tất cả các tra cứu chỉ mục và thay đổi bảng xảy ra cho mỗi INSERT.

Trả lời

1

Rất tiếc, hãy tiếp tục gửi nhận xét cho bạn (có thể là cuối cùng).

Tôi chỉ tìm thấy this article cung cấp ví dụ về chuyển đổi bảng lớn từ MyISAM sang InnoDB, trong khi đây không phải là những gì bạn đang làm, ông sử dụng bảng Bộ nhớ trung gian và mô tả chuyển từ bộ nhớ sang InnoDB theo cách hiệu quả - Thứ tự bảng trong bộ nhớ theo cách mà InnoDB mong đợi nó sẽ được đặt hàng cuối cùng. Nếu bạn không bị ràng buộc với MyISAM, nó có thể đáng xem vì bạn đã có sẵn một bảng bộ nhớ "đúng".

+0

InnoDB sẽ ổn thôi. Điều này rất thông minh ... Tôi thích nó. Cảm ơn bạn đã gửi nhận xét cho tôi. Tôi đánh giá cao nó. :) – brianreavis

3

Nếu bạn có ý định biến nó thành bảng MyISAM, tại sao bạn lại tạo nó trong bộ nhớ ngay từ đầu? Nếu nó chỉ cho tốc độ, tôi nghĩ rằng việc chuyển đổi sang một bảng MyISAM sẽ phủ nhận bất kỳ cải thiện tốc độ nào bạn nhận được bằng cách tạo nó trong bộ nhớ để bắt đầu.

Bạn nói việc chèn trực tiếp vào bảng "trên đĩa" quá chậm (mặc dù tôi không chắc bạn quyết định cách nào khi phương pháp hiện tại của bạn đang dùng ngày), bạn có thể tắt hoặc xóa các ràng buộc duy nhất và sau đó sử dụng truy vấn DELETE sau đó để thiết lập lại tính duy nhất, sau đó kích hoạt lại/thêm các ràng buộc. Tôi đã sử dụng kỹ thuật này khi nhập vào một bảng INNODB trong quá khứ, và tìm thấy ngay cả với sau này xóa nó đã được tổng thể nhanh hơn nhiều.

Một tùy chọn khác có thể là tạo tệp CSV thay vì câu lệnh INSERT và tải tệp đó vào bảng bằng cách sử dụng LOAD DATA INFILE (Tôi tin rằng sẽ nhanh hơn khi chèn, nhưng hiện tại tôi không thể tìm thấy tham chiếu) hoặc bằng cách sử dụng trực tiếp thông qua số CSV storage engine, tùy theo nhu cầu của bạn.

+0

Tôi đã cập nhật câu hỏi để trả lời một số câu hỏi của bạn. Tôi đã tìm thấy các nguồn cho rằng chèn CSV chạy nhanh hơn, nhưng có vẻ như khá hợp lý để kết xuất dữ liệu vào CSV nhiều gigabyte ** rồi ** tải nó vào cơ sở dữ liệu. Đó là thêm một lượng lớn các ổ cứng I/O chậm chạp vào vấn đề. – brianreavis

+0

Nhưng bạn đang đổ vào một tập tin SQL với một bộ INSERTS dù sao không phải là bạn. Tôi không thấy làm thế nào một tập tin CSV là bất kỳ IO khôn ngoan khác nhau? Tôi đã thêm một đoạn văn để giải thích một phương pháp khác có thể khắc phục sự cố "nhập vào MyISAM quá chậm". –

+0

Tôi không thể loại bỏ các ràng buộc duy nhất. Tôi đang sử dụng 'ON DUPLICATE KEY UPDATE' để cập nhật một bản ghi nếu khóa chính (băm) đã tồn tại trong khả năng. Nếu tôi đã loại bỏ ràng buộc, bảng có khả năng sẽ vượt quá 1000 lần kích thước (và đó không phải là một cường điệu). Có rất nhiều UPDATE đang diễn ra --- nó không chỉ là một dump thô vào cơ sở dữ liệu. – brianreavis

1

Tôi không sử dụng mysql nhưng sử dụng máy chủ SQL và đây là quá trình tôi sử dụng để xử lý tệp có kích thước tương tự. Đầu tiên tôi đổ tập tin vào một bảng dàn mà không có ràng buộc. Sau đó, tôi xác định và xóa các dups từ bảng dàn dựng. Sau đó, tôi tìm kiếm các bản ghi hiện có có thể khớp và đặt idfield vào một cột trong bảng dàn dựng. Sau đó, tôi cập nhật nơi cột trường id không phải là null và chèn nơi nó là null. Một trong những lý do tôi làm tất cả các công việc của việc loại bỏ các dups trong bảng dàn là nó có nghĩa là ít tác động trên bảng sản xuất khi tôi chạy nó và do đó nó là nhanh hơn cuối cùng. Toàn bộ quá trình của tôi chạy trong chưa đầy một giờ (và thực sự làm nhiều hơn tôi mô tả vì tôi cũng phải làm mất chuẩn hóa và làm sạch dữ liệu) và ảnh hưởng đến các bảng sản xuất trong thời gian ít hơn 15 phút. Tôi không phải lo lắng về việc điều chỉnh bất kỳ ràng buộc hoặc giảm chỉ mục hoặc bất kỳ điều đó kể từ khi tôi làm hầu hết các chế biến của tôi trước khi tôi nhấn bảng sản.

Cân nhắc xem quy trình simliar có hoạt động tốt hơn cho bạn hay không. Ngoài ra, bạn có thể sử dụng một số loại nhập số lượng lớn để lấy dữ liệu thô vào bảng dàn (tôi kéo tệp biểu diễn 22 GB mà tôi đã dàn dựng trong khoảng 16 phút) thay vì làm việc theo từng hàng không?

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