【问题标题】:PHP - Shorten time to run query for tables from different serversPHP - 缩短运行来自不同服务器的表的查询的时间
【发布时间】:2018-12-21 13:32:42
【问题描述】:

我有 2 个具有不同数据库和服务器的表。服务器 1 中的表 1 包含 destinationinvoice no 列,服务器 2 中的表 2 包含 Invoice NoTotal 列。

我需要总结所有destination 中的total。两个表的唯一匹配值是invoice no,其中WS10001 = 10001。我正在做的方法是select来自服务器1和表1的所有值,使用foreach循环值并在服务器2中运行表2中的查询以总结total

$sql ="select * from table1 group by destination";
$result=mysql_query($sql) or die(mysql_error());

while($myrow=MySQL_fetch_array($result,MYSQL_ASSOC))
{
    extract($myrow);
    $invno=$myrow[2];

    sql2 = "select total from table2 where invoice_no like '%$invno%'";
    $result2 = mysqli_query($conn, $sql);

    while ($row=mysqli_fetch_row($result2)) {
        $value = $row[0];
    }   

    if (destination == "Washington")
    { $wstotal += $value;}
    else if (destination == "Hawaii")
    { $wstotal += $value;}
    else if (destination == "Budapest")
    { $wstotal += $value;}
}

当我使用一个包含 100 条记录的示例表运行它时,此方法运行得非常快,但是当我将它应用于具有超过 10000 条记录的实际表时,它会运行几个小时才能完成它,因为它必须运行查询每个 foreach 循环。
有什么方法可以缩短完成时间,或者我可以保存两个表中的所有值,在 php 中总结?

【问题讨论】:

  • 您还可以运行一个循环来提取所有发票编号。然后运行单个查询以一次性提取所有数据。打开连接是一项非常耗时的操作,在您的情况下,复杂的选择会提高您的速度。
  • 检查this。这可能有助于加入交叉mysql 服务器。

标签: php mysql mysqli


【解决方案1】:

也许只使用 2 个查询!

$sql ="select * from table1 group by destination";
$result=mysql_query($sql) or die(mysql_error());

// Create an empty query
$sql = "";

while($myrow=MySQL_fetch_array($result,MYSQL_ASSOC))
{
    extract($myrow);
    $invno=$myrow[2];

    // Now you add each query to you "global" query : don't forget the ';' at the end
    sql2 .= "select total from table2 where invoice_no like '%$invno%';";
}

现在您只需使用mysqli_multi_querydocumentation)运行此查询一次,然后使用mysqli_next_resultdocumentation)获取每个结果。

很抱歉我用PDO写不了代码,但是逻辑是:

1/ 您使用所有子查询创建一个“大查询”

2/ 你执行这个“大查询”

3/ 你获取所有结果并像以前一样做你的“数学”

4/然后你测试是否有next_result

5/ 你获取下一组结果并做你的“数学”

6/ 重复第 4 步和第 5 步,直到没有更多 next_resut


试试吧,但它应该比为每个循环执行一个查询更好!

希望它足够清楚吗?

【讨论】:

    【解决方案2】:

    您可以使用 GROUP BY 和 SUM 来获得每个目的地的总和:

    SELECT SUM(total) as total 
    FROM table2 
    WHERE destination IN ('Washington','Hawaii','Budapest') 
          AND invoice_no LIKE '%$invno%'
    GROUP BY destination
    

    这样,数据库不需要记住整个数据集,只需要记住分组的总和,在这种情况下最多 3 个结果(这不是 100% 准确,但现在已经足够了)。

    你还有一个 IN() 可以进一步减少数据集,IN() 比 LIKE 快很多。

    如果您没有在“目标”(或另一列具有各种不同值的列,您在查询中经常使用)上没有索引:在其上添加索引。这将缩短查找时间。

    【讨论】:

    • 我需要做一个循环,因为如果有数千条 $invno 记录
    • 它按目的地对结果进行分组,因此在内部它会遍历所有记录,最后您会得到总数、分组和计数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 2015-11-28
    • 1970-01-01
    • 2022-06-24
    • 1970-01-01
    相关资源
    最近更新 更多