为什么 mysql 结果集的循环很慢? (每个周期 1.4 毫秒)

发布于 2024-09-03 04:32:36 字数 932 浏览 5 评论 0原文

$res 包含大约 488k 行,整个循环需要 61 秒!每个周期超过 1.25 毫秒!是什么占用了这么长的时间?

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.041 毫秒),虽然不是最快的,但更好。

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

The $res contains around 488k rows the whole loop takes 61s! that's over 1.25ms per cycle! What is taking all that time?

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'];
}

Now resultset of 10 rows, smaller arrays and performance 30 times higher (0.041ms) not the fastest still but better.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

别靠近我心 2024-09-10 04:32:36

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

Big arrays take more time to allocate memory and handle.
that's why we always ask a database to do all the job and return 10 rows as a final result.

凌乱心跳 2024-09-10 04:32:36

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

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

... {
  $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['..'];
}

这样您只需执行一次数组查找,而不是重复执行,并且可能会显着减少运行时间。尽管如此,将这么多东西放在一个数组中并不会很快。

从长远来看,最好的选择是将数据留在数据库中,只在需要时抓取数据(或者让数据库为您做繁重的工作,如果您想求和/平均/其他) 。

488k is a lot of rows, which means a lot of data. The more items you stick in an array, the more memory has to be allocated and the longer it takes to lookup elements.

As you're executing the same code almost half a million times, it'd be worth optimising the array accesses:

... {
  $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['..'];
}

That way you're only doing the array lookups once instead of repeatedly, and will probably significantly reduce the runtime. Sticking that many things in an array is not going to be fast regardless, though.

In the long run, your best bet is to leave the data in the database and only grab bits as and when you need them (or have the database do the heavy lifting for you, if you're trying to sum/average/whatever).

做个少女永远怀春 2024-09-10 04:32:36

我怀疑一直花费的时间是对 4 维数组的持续访问,其中一些(或全部?)维度是从字符串字段中键入的,这些值本身必须从$row...

我建议您认真重新考虑:

  1. 是否需要内存中的所有内容(
  2. 如果需要),实现最佳访问的最佳数据结构是什么

I suspect that what's taking all the time is the continual access to 4-dimensional arrays, where some (or all?) of the dimensions are being keyed from string fields, those values themselves having to be extracted from $row...

I would suggest you seriously reconsider:

  1. whether you need all that in memory
  2. if so, what the best data structure would be for optimal access
迷乱花海 2024-09-10 04:32:36

这个怎么样:

$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'];
}

What about this:

$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'];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文