为什么这个循环超过mysql结果集慢? (每个周期1.4ms)

时间:2010-05-26 09:34:07

标签: php mysql loops resultset

$ res包含大约488k行,整个循环需要61s!每个周期超过1.25ms!什么是所有的时间?

while($row = $res->fetch_assoc())
{
    $clist[$row['upload_id']][$row['dialcode_id']][$row['carrier_id']]['std'] = $row['cost_std'];
    $clist[$row['upload_id']][$row['dialcode_id']][$row['carrier_id']]['ecn'] = $row['cost_ecn'];
    $clist[$row['upload_id']][$row['dialcode_id']][$row['carrier_id']]['wnd'] = $row['cost_wnd'];
    $dialcode_destination[$row['upload_id']][$row['carrier_id']][$row['dialcode_id']]['other_destination'] = $row['destination_id'];
    $dialcode_destination[$row['upload_id']][$row['carrier_id']][$row['dialcode_id']]['carrier_destination'] = $row['carrier_destination_id'];
}

现在,10行的结果集,更小的阵列和高30倍(0.041ms)的性能不是最快但仍然更好。

while($row = $res->fetch_assoc())
{
    $customer[$row['id']]['name'] = $row['name'];
    $customer[$row['id']]['code'] = $row['customer'];
}

4 个答案:

答案 0 :(得分:2)

大数组需要更多时间来分配内存和处理。 这就是为什么我们总是要求数据库完成所有工作并返回10行作为最终结果。

答案 1 :(得分:1)

488k是很多行,这意味着很多数据。您在数组中添加的项目越多,分配的内存就越多,查找元素所需的时间也就越长。

当您执行相同的代码将近五十万次时,值得优化数组访问:

... {
  $myclist =& $clist[$row['upload_id']][$row['dialcode_id']][$row['carrier_id']];
  $myclist['std'] = $row['..'];
  $myclist['ecn'] = $row['..'];
  ...
  $dest =& $dialcode_destination[$row['upload_id']][$row['carrier_id']][$row['dialcode_id']];
  $dest['..'] = $row['..'];
  $dest['..'] = $row['..'];
}

这样你只需要进行一次数组查找而不是重复查找,并且可能会显着减少运行时间。不管怎样,坚持数组中的许多东西都不会很快。

从长远来看,最好的办法是将数据留在数据库中,只在需要时抓取数据(或者让数据库为你做繁重的工作,如果你试图求和/平均/其它)。

答案 2 :(得分:0)

怀疑一直在进行的是持续访问4维数组,其中一些(或所有?)维度是从字符串字段键入的,这些值本身必须从$row ...

中提取

我建议你认真重新考虑一下:

  1. 你是否需要记忆中的所有内容
  2. 如果是,那么最佳访问的最佳数据结构是什么

答案 3 :(得分:0)

这个怎么样:

$cache = array();
while($row = $res->fetch_assoc())
{
    $key = $row['upload_id']."\n".$row['dialcode_id']."\n".$row['carrier_id'];
    $key1 = "1\n$key";
    if (!array_key_exists($key1, $cache))
      $cache[$key1] = &$clist[$row['upload_id']][$row['dialcode_id']][$row['carrier_id']];

    $ref = &$cache[$key1];
    $ref['std'] = $row['cost_std'];
    $ref['ecn'] = $row['cost_ecn'];
    $ref['wnd'] = $row['cost_wnd'];

    $key2 = "2\n$key";
    if (!array_key_exists($key2, $cache))
      $cache[$key2] = &$dialcode_destination[$row['upload_id']][$row['carrier_id']][$row['dialcode_id']]

    $ref = &$cache[$key2];
    $ref['other_destination']   = $row['destination_id'];
    $ref['carrier_destination'] = $row['carrier_destination_id'];
}