【问题标题】:PHP Foreach large dataPHP Foreach 大数据
【发布时间】:2014-03-20 11:41:39
【问题描述】:

有一个MySQL表有24500行数据,有一个文本文件有26000串数据需要插入到MySQL中,问题是这26000个字符串是什么重复了MySQL表中的数据,所以我们需要比较它们,并且只插入新的/唯一的。

cadastreArray - 来自文本文件的数组

districtArray - mysql 数组

当我尝试做时

foreach ($cadastreArray as $cadastreValue) {
    $districtExist = false;
    foreach ($districtArray as $districtData) {
        if ($cadastreValue[0] == $districtData['1']) {
            $districtExist = true;
            break;
        }
    }
}

if(!$districtExist) { MySQL INSERT ... }

我收到执行时间错误,甚至 3 分钟都不够。 也许您可以提供更好/更快的方法?

【问题讨论】:

  • 在数据库级别进行比较。或者分离过程。执行前 10k 行时,尝试新的 10k,然后尝试新的(直到结束)

标签: php mysql query-optimization


【解决方案1】:

也许您可以将 mysql 字段设置为唯一的,这样当您要插入时,它不会插入,而是会生成错误号并继续执行。所以你不需要比较。

你可以做的另一件事是你可以增加 php.ini 中的 max_execution_time

【讨论】:

  • 除此之外,如果您需要在找到唯一值时更新任何其他字段(例如,上次检查的日期),请查看 ON DUPLICATE KEY UPDATE。
【解决方案2】:

另一种选择。将 26k 文本文件加载到临时表中(LOAD DATA INFILE... 会很快完成)。

然后您可以根据查询执行插入操作,该查询将您的临时表和 LEFT JOIN 与您的完整表进行对比,检查完整表上的字段是否为 NULL。

这里的简单示例脚本:-

<?php

$file = "SomeTextFile.txt";

$sql = "CREATE TEMPORARY TABLE cadastre
(
    field1 INT,
    field2 VARCHAR(255),
    etc...
)";

if(!($db->query($sql)))
{
    die($db->error());// if error, stop script
}

if(!($db->query("LOAD DATA INFILE '$file' INTO TABLE cadastre")))
{
    die($db->error());// if error, stop script
}

$sql = "INSERT INTO district (field1, field2, field3, ......)
        SELECT a.field1, a.field2, a.field3
        FROM cadastre a
        LEFT OUTER JOIN district b
        ON a.field1 = b.field1
        WHERE b.field1 IS NULL";

if(!($db->query($sql)))
{
    die($db->error());// if error, stop script
}

?>

确保临时表和您要插入的表添加了有用的索引。

【讨论】:

    猜你喜欢
    • 2015-04-21
    • 2012-06-30
    • 2021-04-28
    • 2016-02-20
    • 1970-01-01
    • 2018-04-26
    • 1970-01-01
    • 2017-10-10
    • 1970-01-01
    相关资源
    最近更新 更多