2013-08-02 20 views
6

Tôi đang sử dụng insert_batch() để chèn hàng loạt 10000 hàng vào một bảng trong cơ sở dữ liệu. Tôi đang thực hiện một số thử nghiệm và tôi đã nhận thấy rằng đôi khi tất cả 10.000 hàng trở nên được chèn chính xác nhưng trong một số trường hợp, tôi bỏ lỡ hơn 100 hàng trong tổng số bảng của tôi.insert_batch (Code) của Codeigniter với hàng ngàn chèn đã thiếu hồ sơ

Dữ liệu trường trong bản ghi tôi có là ok vì tôi đang sử dụng cùng một dữ liệu cho mỗi thử nghiệm của mình và hầu hết các lần tôi không gặp vấn đề gì. Ví dụ tôi đã thử 20 lần để chèn cùng một dữ liệu vào cơ sở dữ liệu của tôi và ở 19 lần tất cả các hàng sẽ được chèn chính xác nhưng trong một thời gian này tôi sẽ bỏ lỡ 100 hoặc có thể nhiều hàng hơn.

Chức năng cho insert_batch() sau:

protected function save_sms_to_database() { 
    //insert_Batch 
    $datestring = "%Y-%m-%d %h:%m:%s"; 
    $time = time(); 
    $datetime = mdate($datestring, $time); 

    $this->date_sent = $datetime; 

    foreach ($this->destinations as $k => $v) { 
     $sms_data[$k] = array(
      'campaign_id' => $this->campaign_id, 
      'sender_id' => $this->from, 
      'destination' => $v, 
      'token' => md5(time() . 'smstoken' . rand(1, 99999999999)), 
      'message' => $this->body, 
      'unicode' => $this->unicode, 
      'long' => $this->longsms, 
      'credit_cost' => $this->eachMsgCreditCost, 
      'date_sent' => $this->date_sent, 
      'deleted' => 0, 
      'status' => 1, 
      'scheduled' => $this->scheduled, 
     ); 
    } 

    $this->ci->db->insert_batch('outgoingSMS', $sms_data); 
    if ($this->ci->db->affected_rows() > 0) { 
     // outgoingSMS data were successfully inserted  
     return TRUE; 
    } else { 
     log_message('error', $this->campaign_id.' :: Could not insert sms into database'); 
     log_message('error', $this->ci->db->_error_message()); 
     return FALSE; // sms was not inserted correctly 
    } 
} 

Làm thế nào tôi có thể gỡ lỗi insert_batch() cho một dịp như vậy?

Tôi đã thực hiện một số thay đổi trên DB_active_rec.php để thực hiện một số thao tác ghi nhật ký trong quá trình chèn_batch và cho đến nay tôi không thể tái tạo thành công sự cố để xem điều gì đang xảy ra. Nhưng khi vấn đề xuất hiện 2-3 lần lúc đầu và tôi không có những thay đổi lớn đối với logic của mình để khắc phục nó, tôi không thể để nó như thế này vì tôi không tin chức năng insert_batch() của Codeigniter cho sản xuất.

Tôi cũng thêm insert_batch CodeIgniter() chức năng:

public function insert_batch($table = '', $set = NULL) 
{ 
     $countz = 0; 
    if (! is_null($set)) 
    { 
     $this->set_insert_batch($set); 
    } 

    if (count($this->ar_set) == 0) 
    { 
     if ($this->db_debug) 
     { 
      //No valid data array. Folds in cases where keys and values did not match up 
      return $this->display_error('db_must_use_set'); 
     } 
     return FALSE; 
    } 

    if ($table == '') 
    { 
     if (! isset($this->ar_from[0])) 
     { 
      if ($this->db_debug) 
      { 
       return $this->display_error('db_must_set_table'); 
      } 
      return FALSE; 
     } 

     $table = $this->ar_from[0]; 
    } 

    // Batch this baby 
    for ($i = 0, $total = count($this->ar_set); $i < $total; $i = $i + 100) 
    { 

     $sql = $this->_insert_batch($this->_protect_identifiers($table, TRUE, NULL, FALSE), $this->ar_keys, array_slice($this->ar_set, $i, 100)); 

     //echo $sql; 

     $this->query($sql); 
        $countz = $countz + $this->affected_rows(); 
    } 

    $this->_reset_write(); 
      log_message('info', "Total inserts from batch:".$countz); 

    return TRUE; 
} 

cuối cùng log_message() với tổng chèn từ hàng loạt cũng cho thấy vấn đề là khi tôi có chèn ít hơn dự kiến ​​tôi nhận được số không mong đợi chèn vào đó.

Tôi phải nghĩ điều gì đó khác để chèn hàng nghìn hàng vào cơ sở dữ liệu của tôi với trình mã hóa.

bất kỳ ai có bất kỳ đầu mối nào cho loại vấn đề này? Có lẽ nó có liên quan đến ổ đĩa cứng hoặc bộ nhớ của hệ thống trong khi thiếu hiệu năng? Đó là một máy tính cũ với 1gb ram.

EDIT: Theo yêu cầu tôi đặt ở đây là tuyên ngôn INSERT với 9 hàng đang được sản xuất bởi insert_batch() chức năng CodeIgniter của

INSERT INTO `outgoingSMS` (`campaign_id`, `credit_cost`, `date_sent`, `deleted`, `destination`, `long`, `message`, `scheduled`, `sender_id`, `status`, `token`, `unicode`) VALUES ('279',1,'2013-08-02 02:08:34',0,'14141415151515',0,'fd',0,'sotos',1,'4d270f6cc2fb32fb47f81e8e15412a36',0), ('279',1,'2013-08-02 02:08:34',0,'30697000000140',0,'fd',0,'sotos',1,'9d5a0572f5bb2807e33571c3cbf8bd09',0), ('279',1,'2013-08-02 02:08:34',0,'30697000000142',0,'fd',0,'sotos',1,'ab99174d88f7d19850fde010a1518854',0), ('279',1,'2013-08-02 02:08:34',0,'30697000000147',0,'fd',0,'sotos',1,'95c48b96397b21ddbe17ad8ed026221e',0), ('279',1,'2013-08-02 02:08:34',0,'306972233469',0,'fd',0,'sotos',1,'6c55bc3181be50d8a99f0ddba1e783bf',0), ('279',1,'2013-08-02 02:08:34',0,'306972233470',0,'fd',0,'sotos',1,'d9cae1cbe7eaecb9c0726dce5f872e1c',0), ('279',1,'2013-08-02 02:08:34',0,'306972233474',0,'fd',0,'sotos',1,'579c34fa7778ac2e329afe894339a43d',0), ('279',1,'2013-08-02 02:08:34',0,'306972233475',0,'fd',0,'sotos',1,'77d68c23422bb11558cf6fa9718b73d2',0), ('279',1,'2013-08-02 02:08:34',0,'30697444333',0,'fd',0,'sotos',1,'a7fd63b8b053b04bc9f83dcd4cf1df55',0) 

Đó là một chèn hoàn thành.

+0

Trong trường hợp này, tôi khuyên bạn nên chèn các bản ghi trong một vòng lặp thay vì một truy vấn đơn '(insert_batch)'. Và theo cách này, bạn cũng có thể gỡ lỗi (các) truy vấn của mình. –

+0

Bạn có thể cho chúng tôi thấy các truy vấn SQL đang được chạy không? Có lẽ một số không đúng định dạng? Bạn đã cân nhắc sử dụng câu lệnh 'INSERT' khối lượng chưa? – Halcyon

+0

@NiloySaha Tôi thực sự không thể sử dụng vòng lặp cho số lượng lớn chèn như vậy vì nó sẽ làm giảm hiệu suất của hệ thống của tôi. Đặc biệt là trong sản xuất này sẽ là thảm họa. Khi tôi sử dụng một vòng lặp trong khi phát triển cho các chèn tôi không có vấn đề như xa như tôi nhớ nhưng tôi không thể sử dụng logic này cho một số lượng lớn chèn. – sotoz

Trả lời

3

insert_batch() cố gắng tránh chính xác vấn đề của bạn - cố gắng chèn dữ liệu lớn hơn MySQL được định cấu hình để xử lý tại một thời điểm. Tôi không chắc chắn nếu tùy chọn của MySQL cho rằng là max_allowed_packet hoặc cái gì khác, nhưng vấn đề với nó là nó đặt một giới hạn trong byte và không phải là một số hàng.

Nếu bạn sẽ chỉnh sửa DB_active_rec.php, mysql_driver.php hoặc bất kỳ điều gì thích hợp ... hãy thử thay đổi số 100 đó trong vòng lặp for(). 50 nên là một lựa chọn an toàn hơn.

Ngoài ra, FYI - affected_rows() sẽ không trả lại giá trị chính xác nếu bạn đang chèn nhiều hơn 100 hàng qua insert_batch(), do đó không đáng tin cậy để sử dụng nó như là kiểm tra thành công/lỗi. Đó là vì insert_batch() chèn dữ liệu của bạn vào 100 bản ghi cùng một lúc, trong khi affected_rows() sẽ chỉ trả lại dữ liệu cho truy vấn cuối cùng.

+0

cảm ơn câu trả lời của bạn, cho 'affected_rows()' nếu bạn thấy những thay đổi mà tôi đã thực hiện đối với 'DB_active_rec.php', tôi đã đếm chính xác có bao nhiêu chèn được thực hiện với insert_batch và tổng số tôi nhận được là đúng ở mọi thời điểm (vì tôi cũng có thể xác minh nó bằng 'select count (*)'). Tôi sẽ cố gắng thay đổi số vòng lặp như bạn đã nói và thực hiện một số bài kiểm tra ở đó. Nếu mọi thứ suôn sẻ, tôi sẽ chấp nhận câu trả lời của bạn :) – sotoz

+0

Bạn có thể chia sẻ về cách bạn giải quyết vấn đề này không? – siva

0

Các giải pháp của vấn đề này là, bạn cần phải đi trong thư mục /system/database/ và mở tập tin và cập nhật DB_query_builder.php

public function insert_batch($table, $set = NULL, $escape = NULL, $batch_size = 1000)

bạn có thể thiết lập kích thước của yêu cầu của bạn.

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