php實現mysql百萬級資料插入,耗時10s左右

來源:互聯網
上載者:User

標籤:imp   user   time()   rom   代碼   存在   ack   匯入   utf-8   

如題,最近做的一個項目,需求就是這樣,寫個功能模組,實現大量匯入,為客服省點時間(好吧,需求就是需求)。好在插入的資料,都是些連續的數字,所以可以利用

foreach迴圈出這些資料,然後拼接成mysql的insert語句,進行大欄位的批量插入。原理就是這麼個原理,當然過程中有坑,什麼開啟擴充限制,暫且只看邏輯方面的吧。

架構的話,不是laravel,用的ci,執行個體代碼如下:

    /**     * @desc    大量匯入百萬條資料入庫(暫時只有韻達,方法已經寫通用,資料最少5000條,最大100W條)     * @date    2017-10-26 20:45:45     * @param   [int $start_no 起始號;int $end_no 截止號;string $express_type 類型]     * @author  [email protected]     * @return  [type]     */    public function import_million_express_no () {        //基本資料設定        header(‘Content-Type:text/html;charset=utf-8‘);        ini_set(‘memory_limit‘, ‘128M‘);        //設定類型對應資料庫中的表名        $express_to_form = [            ‘test1‘ => ‘from1‘,  //平台1對應的表名            ‘test2‘ => ‘from2‘,  //平台2對應的表名        ];        //擷取參數        $start_no = trim($this->input->post(‘start_no‘));        $end_no = trim($this->input->post(‘end_no‘));        $express_type = trim($this->input->post(‘express_type‘));        //判斷參數是否存在        if(!$start_no || !$end_no){            echo ‘<script>alert("錄入失敗,起始號和截止號不可為空為0");history.back();</script>‘;            return;        }        //起始單號不能大於等於截止單號,錄入數量至少為5000個        if ($start_no >= $end_no) {            echo ‘<script>alert("起始號不能,大於等於截止號!");history.back();</script>‘;            return;        } else {            if ($end_no - $start_no < 5000) {                echo ‘<script>alert("每次錄入號不能小於5000個!");history.back();</script>‘;                return;            }            if ($end_no - $start_no > 1000000) {                echo ‘<script>alert("每次錄入號不能大於1000000個!");history.back();</script>‘;                return;            }        }        //判斷資料類型是否存在        $table_name = $express_to_form[$express_type];        if(!$table_name){            echo ‘<script>alert("快遞類型有誤,無法進行列印!");history.back();</script>‘;            return;        }else{            //判斷初始單號,截止單號是否已經錄入            $sql1 = "select id from {$table_name} where express_no = {$start_no}";            $res1 = $this->db->query($sql1)->row();            if($res1){                echo ‘<script>alert("起始號已存在!");history.back();</script>‘;                return;            }            $sql2 = "select id from {$table_name} where express_no = {$end_no}";            $res2 = $this->db->query($sql2)->row();            if($res2){                echo ‘<script>alert("截止號已存在!");history.back();</script>‘;                return;            }        }        /***上面的一系列判斷的廢話可以不用看,直接看下面怎麼對資料進行邏輯處理***/        //將起始號和截止號進行區間劃分        $length = $end_no - $start_no + 1;        $times  = floor($length / 5000);        $temp_data = [];        for($i=0;$i<$times;$i++){            $temp_data[$i][‘start_no‘] = $start_no;          //起始編號            $temp_data[$i][‘end_no‘]   = $start_no + 4999;   //結束編號            $start_no += 5000;  //下一輪迴圈的起始編號        }        //檢驗數組最後一組資料,判斷是否需要再添加        if($end_no > $temp_data[$times-1][‘end_no‘]){            $temp_data[$times][‘start_no‘] = $temp_data[$times-1][‘end_no‘] + 1;            $temp_data[$times][‘end_no‘] = $end_no;        }        //進行匯入資料庫sql語句的拼接        $add_time = time();        $add_user = $this->session->userdata[‘user_name‘];        $tmp_val = "(‘{$add_time}‘,‘$add_user‘,0,‘%s‘,0),";        for($j=0;$j<count($temp_data);$j++){            //迴圈拼接sql插入語句            $sql = "insert into {$table_name} (field1,field2,field3,field4,field5) values ";            for ($i=$temp_data[$j][‘start_no‘]; $i<=$temp_data[$j][‘end_no‘]; $i++) {                $sql .= sprintf($tmp_val, $i);            }            $sql = trim($sql, ‘,‘) . ‘;‘;            $bool = $this->db->query($sql);            //執行插入有誤,寫進日誌異常表from3中            if(!$bool){                // 記錄日誌                $log_info = array();                $log_info[‘field1‘] = time();                $log_info[‘field2‘] = ‘類型:‘.$express_type.‘執行有誤,單號‘.$temp_data[$j][‘start_no‘].‘-‘.$temp_data[$j][‘end_no‘].‘執行失敗‘;                $log_info[‘field3‘] = $this->session->userdata[‘user_name‘];                $this->db->insert(‘from3‘, $log_info);                //錯誤記錄檔標誌                $err_log_info = TRUE;            }        }        //資料返回        if($err_log_info){            echo ‘<script>alert("部分號執行失敗,請聯絡管理員解決!");history.back();</script>‘;        }else{            echo ‘<script>alert("資料執行成功!!!");history.back();</script>‘;        }        return;    }

  上面就是封裝的一個完整的類,參數驗證什麼的,可以不用看了,直接看sql語句拼接,其實最後發現吧,做出來也沒啥。經過測試,基本耗時在10s左右徘徊,恩恩,暫時先這樣,有好的思路,歡迎交流。不說了,得繼續加班去了,233

php實現mysql百萬級資料插入,耗時10s左右

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.