使用PHPxcel减少数据库插入的执行时间

时间:2016-11-26 04:44:59

标签: php mysql zend-framework2

我正在尝试将包含20k +行的excel文件工作表插入到我的数据库表中。我正在使用Zend Framework(ZF2),PHPExcel和mysql。我的问题是,当我试图将数据插入mysql表时,它需要超过10分钟。一切都很完美,但唯一的问题是随着时间的推移。任何人都知道如何减少执行时间。在此先感谢,以下是我的示例代码:

for($i=2;$i<=$highestRow;++$i)
            {
                $data = array(
                    'tid' => $posts[$i][0],
                    'PID' => $posts[$i][1],
                    'RNO' => $posts[$i][2], 
                    'BCD' => $posts[$i][3],
                    'ENO' => $posts[$i][4],
                    'ARC' => $posts[$i][5],
                    'LD' => '',
                );
                $insert = $sql->insert('table');
                $insert->values($data);
                $selectString = $sql->getSqlStringForSqlObject($insert);
                $results = $this->adapter->query($selectString, Adapter::QUERY_MODE_EXECUTE);
            }

3 个答案:

答案 0 :(得分:2)

很可能是InnoDB引擎的问题。默认情况下,此引擎过于谨慎,并且不会使用磁盘缓存,以确保在返回成功消息之前确实已将数据写入磁盘。所以你基本上有两种选择。

  1. 大部分时间你都不关心确认的写作。因此,您可以通过将此mysql选项设置为零来配置mysql:

    innodb_flush_log_at_trx_commit = 0
    

    只要以这种方式设置,你的InnoDB写入速度几乎与MyISAM一样快。

  2. 另一种选择是将所有写入包装在单个事务中。因为它只需要所有写入的单一确认,所以它也很合理。

答案 1 :(得分:1)

在前两个答案的基础上,我将通过以下方式解决问题:

首先我对PHPExcel持怀疑态度。我从未使用过图书馆,但我heard that it can be pretty slow

所以我要做的第一件事是注释掉实际写入数据库的行,看看简单地迭代输入数据需要多长时间。

如果只需要很长时间,那么理想的解决方案就是将其作为用户的问题并要求使用普通的CSV文件。

如果接受excel文件是一项艰难的要求,那么您必须优化使用PHPExcel的方式。请参阅我上面链接的SO页面作为尝试提高性能的起点。

下一步,根据Your Common Sense's second suggestion优化数据库端。

在事务中包装所有插入有两个优点。正如YCS提到的那样,这将允许innodb推迟确认写入直到结束。也许更重要的是,将插入包装在单个事务中将导致InnoDB将更新索引推迟到提交时间。在您当前的代码中,InnoDB在每次插入后都会更新标记。

这可能会有所改善,但即使使用每次插入提交,插入20k记录也不会接近10分钟。因此,在您担心秒而不是几分钟之前,数据库端的攻击事件不太可能产生重大改进。

答案 2 :(得分:0)

如果您使用大型数据集,那么您可能需要考虑一种不将文件加载到内存中的不同方法。

就个人而言,我会转换为CSV并将数据集导入到具有与文件匹配的列的临时数据库表中。 LOAD DATA INFILE命令专门用于执行此操作,通常会在中处理非常大的文件。

导入数据后,您可以使用 SQL 的所有功能进行查询,并将数据插入您真正想要的位置。