【发布时间】:2015-06-29 22:16:35
【问题描述】:
我有一个超过 100.000 行的 CSV 文件,每行有 3 个用分号分隔的值。总文件大小约为。 5MB。
CSV 文件格式如下:
stock_id;product_id;amount
==========================
1;1234;0
1;1235;1
1;1236;0
...
2;1234;3
2;1235;2
2;1236;13
...
3;1234;0
3;1235;2
3;1236;0
...
我们有 10 只股票,它们在 CSV 中的索引为 1-10。在数据库中,我们将它们保存为 22-31。
CSV 是按 stock_id、product_id 排序的,但我觉得没关系。
我有什么
<?php
session_start();
require_once ('db.php');
echo '<meta charset="iso-8859-2">';
// convert table: `CSV stock id => DB stock id`
$stocks = array(
1 => 22,
2 => 23,
3 => 24,
4 => 25,
5 => 26,
6 => 27,
7 => 28,
8 => 29,
9 => 30,
10 => 31
);
$sql = $mysqli->query("SELECT product_id FROM table WHERE fielddef_id = 1");
while ($row = $sql->fetch_assoc()) {
$products[$row['product_id']] = 1;
}
$csv = file('export.csv');
// go thru CSV file and prepare SQL UPDATE query
foreach ($csv as $row) {
$data = explode(';', $row);
// $data[0] - stock_id
// $data[1] - product_id
// $data[2] - amount
if (isset($products[$data[1]])) {
// in CSV are products which aren't in database
// there is echo which should show me queries
echo " UPDATE t
SET value = " . (int)$data[2] . "
WHERE fielddef_id = " . (int)$stocks[$data[0]] . " AND
product_id = '" . $data[1] . "' -- product_id isn't just numeric
LIMIT 1<br>";
}
}
问题是echo 写下 100k 行太慢了,需要很长时间。我不确定 MySQL 会做什么,它是否会更快,或者需要多少时间。我这里没有测试机,所以我担心在产品服务器上进行测试。
我的想法是将 CSV 文件加载到更多变量(更好的数组)中,如下所示,但我不知道为什么。
$csv[0] = lines 0 - 10.000;
$csv[1] = lines 10.001 - 20.000;
$csv[2] = lines 20.001 - 30.000;
$csv[3] = lines 30.001 - 40.000;
etc.
我发现例如。 Efficiently counting the number of lines of a text file. (200mb+),但我不确定它对我有什么帮助。
当我将 foreach 替换为 print_r 时,我会在
知道如何更新数据库中的这么多记录吗?
谢谢。
【问题讨论】:
-
作为替代方案,您可以创建一个文件,然后使用
load data local infile这将比在 PHP 中完成所有加载要快得多 -
你为什么使用会话?在循环之外使用数组存储而不是每次都重置,听起来你在 1-10 和 21-31 之间有一个固定的映射,所以你可以用简单的 case 语句替换所有数组查找(或者如果有的话)然后使用 fgetcsv() 循环读取您的 csv 并根据需要插入要快得多。你似乎已经为一些你可以在不到 5 行的时间内完成的事情写了很多代码 oO
-
@Dave:真的有 5 行吗?也许可能,我不是程序员,尽我所能。您能在 asnwer 中告诉我更多信息吗?我用于加载 csv 文件的会话仅一次,但确实该脚本只会启动一次。即将删除会话。
-
作为旁注:$_SESSION['products'][$row['value']] = 1;将不起作用,因为 $row['value'] 始终为空。您应该改用 $row['product_id']。
-
@EdsonMedina:只是错字,抱歉。会话由 product_ids 正确填充。