Php 从DB2数据库填充MySQL数据库
我目前有一个脚本,用于从DB2服务器填充MySQL数据库。这是可行的,但它似乎以极慢的速度将行插入MySQL。脚本运行时,服务器进程正在以大约1%的CPU执行,我想知道如何加快插入速度 出于安全原因,DB2数据库管理员只向我们提供了数据库中所需表的只读视图 这是我的剧本: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
<?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是如何执行操作后,为了加快插入速度,我做了以下操作:
- 使用(即关闭自动提交):
。每个事务的查询量是有限的,尽管我很确定当InnoDB缓冲区填满时MySQL无论如何都会提交$this->mysql->beginTransaction()
- :
。DB2数据库具有相当高的完整性,因此这是一个安全的操作设置外键检查=0
- 禁用唯一密钥检查:
。DB2数据库已经强制使用了唯一密钥,因此这是安全的李>设置唯一密钥检查=0
- :
设置会话事务隔离级别读取未提交
进一步考虑的事情是,但是这些不能在服务器访问受限的情况下发生改变。
此页面也可能会有所帮助,尽管它列出了此处列出的大部分内容:目前这不是我们的选项,因为我们对服务器的控制非常有限,但是当我们迁移到较新的服务器时,我会记住这一建议。谢谢
<?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();
}
}
}
}