使用php更新数千个mysql行

时间:2016-01-18 14:43:09

标签: php mysql mysqli

我有一个脚本需要每晚更新一个值 - 每晚。

我的mysql数据库有119k行,分为35k行。

对于这些行中的每一行,我需要计算最高值和最低值,并使用这些行之间的新百分比差异更新行。

现在我甚至无法以50 +

的限制执行更新

我的代码:

$query_updates = mysqli_query($con,"SELECT partner FROM trolls WHERE GROUP BY partner LIMIT 0, 50") 
    or die(mysqli_error($con));

    while($item = mysqli_fetch_assoc($query_updates)) {

        $query_updates_prices = mysqli_query($con,"SELECT 
                                                        MIN(partner1) AS p1, 
                                                        MAX(partner2) AS p2, 
                                                        COUNT(partner3) AS p3 
        FROM trolls WHERE partner='". $item["partner"] ."'") 
        or die(mysqli_error($con));

        $partner = mysqli_fetch_assoc($query_updates_prices);
        $partner1 = $partner["p1"];
        $partner2 = $partner["p2"];
        $difference = $partner1 - $partner2;
        $savings = round($difference / $partner1 * 100);

        $partner3 = $prices["p3"];

        $update_tyre = mysqli_query($con, "UPDATE trolls SET 
                                                                        partner1='". $partner1 ."', 
                                                                        partner2='". $partner2 ."', 
                                                                        partner3='". $partner3 ."', 
                                                                        partner4='". $savings ."' 

        WHERE partner='". $item["partner"] ."'") 
        or die(mysqli_error($con));

        echo '<strong>Updated: '. $item["partner"] .'</strong><br>';

    }

如何让这更简单/更能执行?

2 个答案:

答案 0 :(得分:0)

+1的cron,命令行运行也可以帮助你,因为它不会超时。但是,通过锁定表可能会出现组问题。 说实话(你不会喜欢这个)但是如果你在一个有大量领域的领域做一个小组,那么我会说你做错了什么。 所以我会看看重做桌子,找一张合作伙伴的桌子。然后引用那些有帮助的巨魔。

但是为了给你一个解决方案只是为了加快这一点,你可以转向更好的数据库/表设置并解决锁定问题。我会这样做。

第1步。 创建一个名为

的表
Partners
Field1: partner_id
Field2: partner
Field3: p1
Field4: p2
Field5: p3

第2步: 运行查询 SELECT partner FROM trolls(将来可以更改为SELECT * FROM partners)

第3步: 检查他们是否在合作伙伴中 - 如果没有插入

第4步: 运行你的

SELECT 
MIN(partner1) AS p1, 
MAX(partner2) AS p2, 
COUNT(partner3) AS p3 
FROM trolls WHERE partner='". $item["partner"] ."'

第5步: 将值中的值更新到Partners表中,并(暂时)更新trolls表。

完成。

哦,并且它已经没有添加到合作伙伴字段的索引。

答案 1 :(得分:0)

你可以在一个中完成这两个选择:

SELECT partner, MIN(partner1) AS p1, MAX(partner2) AS p2, COUNT(partner3) AS p3 
FROM trolls GROUP BY partner LIMIT 0, 50

在巨魔(伙伴)上创建BTREE索引而不锁定表:

CREATE INDEX CONCURRENTLY IX_TROLLS_PARTNER ON trolls USING btree(partner);

如果您仍然选择将这2个SELECT分开,请使用PDO-&gt; prepare而不是PDO-&gt;查询,PDO->prepare doc on php.net

  

为将使用不同参数值多次发出的语句调用PDO :: prepare()和PDOStatement :: execute()通过允许驱动程序协商客户端和/或服务器端缓存来优化应用程序的性能查询计划和元信息

如果它太低了,可能会将php.ini max_execution_time更改为更高的值(我保持300(5分钟)但每种情况都是一个案例:P)。