Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 从DB2数据库填充MySQL数据库_Php_Mysql_Performance_Db2_Database Performance - Fatal编程技术网

Php 从DB2数据库填充MySQL数据库

Php 从DB2数据库填充MySQL数据库,php,mysql,performance,db2,database-performance,Php,Mysql,Performance,Db2,Database Performance,我目前有一个脚本,用于从DB2服务器填充MySQL数据库。这是可行的,但它似乎以极慢的速度将行插入MySQL。脚本运行时,服务器进程正在以大约1%的CPU执行,我想知道如何加快插入速度 出于安全原因,DB2数据库管理员只向我们提供了数据库中所需表的只读视图 这是我的剧本: <?php $selectQuery = "SELECT PK AS COL1, COL2, C

我目前有一个脚本,用于从DB2服务器填充MySQL数据库。这是可行的,但它似乎以极慢的速度将行插入MySQL。脚本运行时,服务器进程正在以大约1%的CPU执行,我想知道如何加快插入速度

出于安全原因,DB2数据库管理员只向我们提供了数据库中所需表的只读视图

这是我的剧本:

<?php

$selectQuery = "SELECT 
                    PK AS COL1,
                    COL2,
                    COL3,
                    COL4,
                    CASE WHEN DATE > '" . date('Y-m-d') . "'
                      THEN 1
                      ELSE 0
                      END AS COL5
                FROM table1";

$insertQuery = "INSERT INTO `table1` (
                    `fk`,
                    `col2`,
                    `col3`,
                    `col4`,
                    `col5`,
                    `last_updated`
                )
                SELECT :col1, f.`fid`, :col3, :col4, :col5, NOW()
                    FROM f
                    WHERE f.`code` = :col2
                    LIMIT 1
                ON DUPLICATE KEY UPDATE
                    `col2` = VALUES(col2),
                    `col3` = VALUES(col3),
                    `col4` = VALUES(col4),
                    `col5` = VALUES(col5),
                    `last_updated` = NOW();";

$paramTypes = array(
    'col1' => PDO::PARAM_STR,
    'col2' => PDO::PARAM_STR,
    'col3' => PDO::PARAM_STR,
    'col4' => PDO::PARAM_STR,
    'col5' => PDO::PARAM_BOOL
);
顺便说一下,这个
populate
方法调用了六次,每个表调用一次。我只展示了一张桌子。表的大小从20行到2100万行不等


我想我可以在查询中绑定大写参数,以避免
foreach
中的所有
strtolower
函数,但是除了这一微小的更改之外,还有什么关于如何提高脚本性能的建议吗?

无论您做什么,按行插入数据都不会很好地执行。在我看来,更好的方法是使用DB2EXPORT命令将DB2表数据提取到CSV文件中,然后使用MySQL LOAD data将它们加载到目标数据库中。我不太熟悉PHP,但我认为它应该允许您使用exec()运行外部命令


您至少需要安装DB2 Data Server运行时客户端,才能运行DB2命令行处理器进行导出。

尝试将整个数据导出为csv文件格式,然后使用加载数据实用程序将其加载到MySQL数据库中。加载和导出实用程序的执行速度肯定比获取一行并逐个插入要快。

在简要调查InnoDB是如何执行操作后,为了加快插入速度,我做了以下操作:

  • 使用(即关闭自动提交):
    $this->mysql->beginTransaction()
    。每个事务的查询量是有限的,尽管我很确定当InnoDB缓冲区填满时MySQL无论如何都会提交
  • 设置外键检查=0
    。DB2数据库具有相当高的完整性,因此这是一个安全的操作
  • 禁用唯一密钥检查:
    设置唯一密钥检查=0
    。DB2数据库已经强制使用了唯一密钥,因此这是安全的
  • 设置会话事务隔离级别读取未提交

进一步考虑的事情是,但是这些不能在服务器访问受限的情况下发生改变。


此页面也可能会有所帮助,尽管它列出了此处列出的大部分内容:

目前这不是我们的选项,因为我们对服务器的控制非常有限,但是当我们迁移到较新的服务器时,我会记住这一建议。谢谢
<?php

class SyncObject {
    private $db2;
    private $db2_user = '...';
    private $db2_pass = '...';
    private $db2_dbname = '...';
    private $db2_host = 'secure.example.net';
    private $db2_port = ...;

    private $mysql;

    public function __construct() {
        // Establish a DB2 connection
        $this->db2 = db2_pconnect("DATABASE={$this->db2_dbname};HOSTNAME={$this->db2_host};PORT={$this->db2_port};PROTOCOL=TCPIP;UID={$this->db2_user};PWD={$this->db2_pass};", '', '');

        // Establish a MySQL connection
        $this->mysql = new PDO('mysql:host=secure-mysql.example.net;port=...;dbname=...', '...', '...', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
}

    public function populate($selectQuery, $insertQuery, $paramTypes = array()) {

        $insStmt = $this->mysql->prepare($insertQuery);

        foreach ($paramTypes as $parameterName => $parameterType) {

            $$parameterName = '';

            $insStmt->bindParam(":$parameterName", $$parameterName, $parameterType);
        }

        // Retrieve the data

        $stmt = db2_exec($this->db2, $selectQuery);

        while ($row = db2_fetch_assoc($stmt)) {
            foreach ($row as $fieldName => &$fieldValue) {

                $fieldName = strtolower($fieldName);

                $$fieldName = trim($fieldValue);

                $insStmt->execute();
            }
        }
    }
}