我正在尝试构建一个脚本,我需要读取txt
文件并使用文件中的行执行某些过程。例如,我需要检查ID是否存在,如果信息已更新,如果是,则更新当前表,如果否,则在另一个临时表上插入一个新行,以便稍后手动检查。
这些文件可能包含超过20,30,000行。
当我刚读取文件并从行中打印一些dummie内容时,它需要40-50ms。但是,当我需要连接到数据库进行所有这些验证时,由于超时,它会在结束前停止。
这就是我到目前为止所做的事情:
$handle = fopen($path, "r") or die("Couldn't get handle");
if ($handle) {
while (!feof($handle)) {
$buffer = fgets($handle, 4096);
$segment = explode('|', $buffer);
if ( strlen($segment[0]) > 6 ) {
$param = [':code' => intval($segment[0])];
$codeObj = Sql::exec("SELECT value FROM product WHERE code = :code", $param);
if ( !$codeObj ) {
$param = [
':code' => $segment[0],
':name' => $segment[1],
':value' => $segment[2],
];
Sql::exec("INSERT INTO product_tmp (code, name, value) VALUES (:code, :name, :value)", $param);
} else {
if ( $codeObj->value !== $segment[2] ) {
$param = [
':code' => $segment[0],
':value' => $segment[2],
];
Sql::exec("UPDATE product SET value = :value WHERE code = :code", $param);
}
}
}
}
fclose($handle);
}
这是我的Sql类,用于连接PDO并执行查询:
public static function exec($sql, $param = null) {
try {
$conn = new PDO('mysql:charset=utf8mb4;host= '....'); // I've just deleted the information to connect to the database (password, user, etc.)
$q = $conn->prepare($sql);
if ( isset($param) ) {
foreach ($param as $key => $value) {
$$key = $value;
$q->bindParam($key, $$key);
}
}
$q->execute();
$response = $q->fetchAll();
if ( count($response) ) return $response;
return false;
} catch(PDOException $e) {
return 'ERROR: ' . $e->getMessage();
}
}
如您所见,我通过Sql::exec()
执行的每个查询都在打开一个新连接。我不知道这是否可能是导致此过程延迟的原因,因为当我不进行任何Sql查询时,该脚本在ms
内运行。
或者代码的其他部分可能导致此问题?
答案 0 :(得分:0)
首先,让你的功能像这样, 避免多重连接,也摆脱无用的代码。
public static function getPDO() {
if (!static::$conn) {
static::$conn = new PDO('mysql:charset=utf8mb4;host= ....');
}
return static::$conn;
}
public static function exec($sql, $param = null) {
$q = static::getPDO()->prepare($sql);
$q->execute($param);
return $q;
}
然后为code
字段
然后使用单个INSERT ... ON DUPLICATE KEY UPDATE查询而不是您的thrree查询
您可能还想在事务中包装插入内容,它可能会最多加快插入次数。