2012-03-09 44 views
5

Tôi có một ứng dụng PHP/MySql viết nhanh, đang viết nhanh, chèn các hàng mới với tốc độ hàng chục hoặc hơn mỗi giây vào bảng INNODB vài triệu hàng.MySql INSERT vs PHP file_put_contents

Tôi bắt đầu sử dụng các câu lệnh INSERT thời gian thực và sau đó chuyển đến tệp file_put_contents của PHP để ghi các mục vào tệp và LOAD DATA INFILE để lấy dữ liệu vào cơ sở dữ liệu. Cách tiếp cận nào tốt hơn?

Tôi có nên cân nhắc lựa chọn thay thế nào không? Làm thế nào tôi có thể mong đợi hai phương pháp để xử lý va chạm và tăng tải trong tương lai?

Cảm ơn!

+0

Một cách khác là ghi vào bảng phụ, sau đó thực hiện số lượng lớn 'chèn vào ... chọn từ' vào bảng chính, nếu ghi vào bảng chính đang trở thành một vấn đề. –

Trả lời

3

Hãy suy nghĩ về LOAD DATA INFILE làm phương pháp chèn hàng loạt dữ liệu. Nó giúp loại bỏ chi phí của việc nạp lên một truy vấn chèn cho mỗi câu lệnh do đó nhanh hơn nhiều. Tuy nhiên, bạn mất một số điều khiển khi xử lý lỗi. Việc xử lý lỗi trên một truy vấn chèn đơn giản hơn nhiều so với một hàng ở giữa tệp.

+0

Bạn có thể sử dụng cú pháp chèn vào các giá trị bảng (row1), (row2), ..., (rowN); để chèn bao nhiêu hàng tùy thích với một truy vấn. Bạn cũng có thể nối thêm "... vào bản cập nhật khóa trùng lặp ..." để chỉ định cách xử lý các va chạm khóa duy nhất – atxdba

+0

@atxdba Đó là một ý tưởng khủng khiếp về chèn lớn. – feketegy

+0

@feketegy Horrible như thế nào? Hiệu suất? http://tinyurl.com/7jmzbcp Là bài viết SO đặt ra làm thế nào nó là tốt hơn và ưa thích. Cấp cho bạn không muốn tải một số hợp đồng dữ liệu trong một chèn nhưng làm cho một tuyên bố chăn undefined rằng nó là khủng khiếp nó chỉ đơn giản là sai. Ngay cả mysqldump sẽ tạo ra các đợt chèn theo mặc định. Nếu bạn đang nói về các tập dữ liệu tải dữ liệu thực sự lớn thì có thể tốt hơn, tôi sẽ không tranh cãi điều đó. Tôi thực sự chỉ đang chỉ ra cú pháp có sẵn. – atxdba

0

Cách chúng ta đối phó với chèn của chúng tôi là để chúng được gửi đến hệ thống hàng đợi thư như ActiveMQ. Từ đó chúng tôi có một ứng dụng riêng biệt tải các chèn bằng cách sử dụng LOAD DATA INFILE theo lô khoảng 5000. Xử lý lỗi vẫn có thể xảy ra với infile tuy nhiên nó xử lý chèn nhanh hơn nhiều. Nếu thiết lập hàng đợi tin nhắn nằm ngoài phạm vi ứng dụng của bạn thì không có lý do gì mà tệp_put_contents không phải là tùy chọn có thể chấp nhận được - Đặc biệt nếu nó đã được triển khai và hoạt động tốt.

Ngoài ra, bạn có thể muốn kiểm tra việc vô hiệu hóa các chỉ mục trong quá trình ghi để xem điều đó có cải thiện hiệu suất hay không.

+0

Lưu ý tốt về việc tắt chỉ mục - cảm ơn bạn – user1259956

+0

Một điểm khác cần xem xét là nơi nút cổ chai cho hệ thống cụ thể của bạn là. Hãy thử sử dụng iostat và vmstat để xác định nơi chậm chạp của bạn và nơi bạn nên tập trung nỗ lực của mình. Tùy thuộc vào những gì bạn đang làm với dữ liệu của bạn có nhiều giải pháp để lưu trữ, một số trong số chúng nhanh hơn nhiều nếu không phải là ACID thân thiện. – RumpRanger

0

Có vẻ như bạn không nên sử dụng innoDB. Bất kể, hàng chục lần chèn trên giây không phải là vấn đề ngay cả đối với phần cứng crappy - trừ khi, có thể, mô hình dữ liệu của bạn rất phức tạp, nhưng với điều đó, LOAD DATA INFILE rất tốt vì trong số những thứ khác, nó chỉ xây dựng lại các chỉ mục một lần, như trái ngược với trên mỗi chèn. Vì vậy, sử dụng các tập tin là một cách tiếp cận phong nha, nhưng hãy chắc chắn rằng bạn mở chúng trong phụ thêm chế độ duy nhất.

về lâu dài (1k + ghi/s), hãy xem các cơ sở dữ liệu khác - đặc biệt là cassandra để viết các ứng dụng nặng.

+0

Việc lập chỉ mục cũng đang trong tâm trí của tôi. Mà sẽ được nhanh hơn cho mỗi viết - phụ thêm vào một tập tin phẳng hoặc chèn vào một cơ sở dữ liệu? Họ sẽ xử lý các yêu cầu đồng thời như thế nào? – user1259956

+0

nó thực sự phụ thuộc, bạn cần phải chạy thử nghiệm và tìm ra nó cho môi trường của bạn. Phụ thêm vào một tập tin chỉ là nguyên tử nếu bạn giữ dữ liệu trong một giới hạn (tôi tin rằng 4K của nó trên Linux), o/w bạn sẽ có vấn đề với đồng thời – miki

2

Tùy thuộc vào việc bạn có thể đủ khả năng để dữ liệu được chèn bởi PHP không có sẵn ngay lập tức trong bảng không, thì INSERT DELAYED có thể là một tùy chọn.

MySQL sẽ chấp nhận dữ liệu được chèn vào và sẽ xử lý việc chèn sau này, đưa nó vào hàng đợi. Vì vậy, điều này sẽ không chặn ứng dụng PHP của bạn trong khi MySQL đảm bảo dữ liệu được chèn sau này.

As it says in the manual:

Một lợi ích lớn của việc sử dụng INSERT HOÃN là chèn từ nhiều khách hàng đang đi kèm với nhau và viết bằng một khối. Điều này là nhanh hơn nhiều so với thực hiện nhiều chèn riêng biệt.

Tôi đã sử dụng này cho dữ liệu khai thác gỗ, nơi một mất mát dữ liệu không gây tử vong nhưng nếu bạn muốn được bảo vệ khỏi tai nạn máy chủ khi dữ liệu từ INSERT DELAYED đã không được đưa vào bài viết nào, bạn có thể nhìn vào sao chép những thay đổi đi để một máy nô lệ chuyên dụng.

0

nếu bạn thực hiện tuyến chèn chèn sql, hãy bọc các câu lệnh thực thi lệnh pdo trong giao dịch. làm như vậy sẽ đẩy nhanh quá trình.