当前位置:Gxlcms > 数据库问题 > MySQL 对 MyISAM、InnoDB 批量插入经验总结

MySQL 对 MyISAM、InnoDB 批量插入经验总结

时间:2021-07-01 10:21:17 帮助过:60人阅读

null|array $data * @param int $rows * @return string */ protected function getInsertFieldValues(array $data, $rows) { $data && $this->data($data); $data = $this->getData(); $fields = $holders = $bind = array(); foreach ($data as $k => $v) { $fields[] = $k; $holders[] = ‘?‘; } $vals = ‘ , ( ‘ . implode(‘ , ‘, $holders) . ‘ )‘; return ‘( ‘ . implode(‘ , ‘, $fields) . ‘ ) VALUES ‘. ltrim(str_repeat($vals, $rows), ‘ ,‘); }
    /**
     * 将多行数据共用一个 INSERT 语句进行批量插入
     * 速度最快, 但插入失败时只能大范围的元素块, 而不能精确到某一行
     * 其次, 每次插入占位符总数不能超过 65535 个, 程序将自动判断占位符数量并对列表进行分页插入
     * 该方法对 innoDB 引擎和 MyISAM 引擎速度相差不大
     * @param array $list
     * @return int|array 成功则返回行数, 失败返回包含错误部分的所有元素(但不能精确到具体某一行)
     * @throws Exception
     */
    protected function addAllMoreInRow(array $list) {
        $rowsNum = count($list);
        if (isset($list[0])) $row = $list[0];
        else {
            $row = array_shift($list);
            array_unshift($list, $row);
        }
        // 每一行的占位符数量
        $holdersNum = count($row);
        // 计算对数组分割每块最大元素数量
        $chunkSize = min(array(50000, floor(65535/$holdersNum)));
        // 获得批量插入语句模版并进行预编译
        $query[0] = ‘INSERT INTO‘;
        $query[1] = $this->getTable();
        $query[2] = $this->getInsertFieldValues($row, $chunkSize);
        $this->prepare($query);
        // 保存之前已设置的绑定数据
        $defaultBind = $this->bind ? $this->bind : array();
        // 对数组按页分组
        $list = array_chunk($list, $chunkSize, true);
        // 最后一页索引
        $last = count($list) - 1;
        // 将数组分成多块单独绑定数据再进行按页插入
        foreach ($list as $p=>$block) {
            // 最后一页因数量不一致需重置预编译模版
            if ($p == $last) {
                $this->reset();
                $query[2] = $this->getInsertFieldValues($row, count($block));
                $this->prepare($query);
            }
            $this->bind = $defaultBind;
            foreach ($block as $r=>$data) {
                foreach ($data as $k=>$v) {
                    $this->bind[] = $v;
                }
            }
            $result = $this->execute($this->bind);
            if (! $result) return $block;
        }
        $this->reset();
        return $rowsNum;
    }

版权声明:本文为博主原创文章,未经博主允许不得转载。http://blog.csdn.net/zhouzme

MySQL 对 MyISAM、InnoDB 批量插入经验总结

标签:mysql   myisam   innodb   批量插入   instance   

人气教程排行