【问题标题】:Array compare, while loops and efficency数组比较、while 循环和效率
【发布时间】:2012-03-17 18:20:30
【问题描述】:

我正在构建一个简单的专辑和曲目 web 应用程序,但我在检索正确信息并使其高效时陷入困境。我有两张桌子 - 专辑大约有 500 个项目,曲目大约有 5000 个。

所以我从一个正常的 while 循环开始:

$albumQuery = "SELECT * FROM `album` ORDER BY album ASC";
$albumDatabase = mysql_query($albumQuery, $admin) or die(mysql_error()); 

while($albumRow = mysql_fetch_array($albumDatabase)){
    $list = "";
    $list.="build some html for showing later";

这是我遇到效率问题的地方:

    $trackQuery = "SELECT track, album FROM `track` WHERE album = '{$album}' ORDER BY filename ASC";
    $trackDatabase = mysql_query($trackQuery, $admin) or die(mysql_error());

    while($trackRow = mysql_fetch_array($trackDatabase)){
        $list.="track html info";
    }

    $listarray[] = $list;
}

natcasesort($listarray);

然后我稍后在正文中运行一个 foreach

foreach ($listarray as $v){
    $first_letter = strtoupper(mb_substr($v,9,1));
    if($tmp!==$first_letter){
        $tmp = $first_letter;
        echo '<div class="alphaHolder">'.$tmp.'</div>';
    }
    echo $v;
}

这很有效,除了可能非常低效。

我可以让它以正确的方式和顺序反刍所有信息。

作为一个实验,我将第二个 while 循环放在父循环之外,并将此信息放入它自己的数组中。然后运行这个:

foreach($trackArray as $k => $v){
    if(in_array($v['album'], $albumRow)){
        $list.="track html info";
    }
}

但后来我意识到,每次它通过父循环运行时,它都会在 5000 个项目上重新运行 foreach,然后执行 in_array 500 次。这显然需要很长时间并且通常会使浏览器崩溃。将我引向原来的嵌套 while 循环,它的效率和复杂度更高。

我已经开始认为 array_intersect 可能是解决方案,但我不想找错树。

可能有太多循环,你在做什么,但我需要自然排序和字母/数字标题反刍。

屏幕:http://ink361.com/#/photos/133115598501394804_9688917

【问题讨论】:

  • 你忘了提什么。像整个混乱的目标这样的小事。你的目标是什么?要在单个页面上构建包含 5000 条曲目的列表?
  • 是的,包含所有专辑的整页,然后是每个专辑下方的相应曲目。
  • 好吧,我可以告诉你,一个包含 5000 行的 HTML 页面总是效率低下且速度慢。
  • 请不要在您的帖子上签名。以前的签名被删除是有原因的。

标签: php mysql arrays while-loop


【解决方案1】:

我认为,您应该重新考虑“曲目”查询。您可以加入“专辑”表,将每个专辑行添加到每个曲目行,并对结果数组进行一次循环,以生成所需的结果。

无论如何,您都可以在$listarray[] = $list; 之前完成所有foreach ($listarray as $v){ 的事情。

而且,既然已经使用 SQL 进行排序,为什么还要使用 PHP 进行排序。你真的需要那个吗?此外,您真的需要同时访问所有这 5000 个项目吗?不是每个男孩都希望完成排序,我的猫希望按歌曲长度或类型排序,你考虑得够多了吗?

为了更有效地处理效率,最好提供示例数据,以及独立工作的“案例代码”。您的代码此时似乎已损坏。也许,你应该学习你的 php 编码实践。

【讨论】:

  • 好的。那是下一步 - 加入查询。我希望应用程序工作的方式确实需要 sql 所没有的自然排序方面。是的,我意识到提供更多代码会有所帮助,但我手头并没有全部 - 我所提供的是这里发生的事情的要点及其记忆。稍后将在项目中以其他方式控制排序 - 这就是“我”希望它目前的工作方式。
  • 效率是个棘手的问题。这些天的主要话题,不是机器功率,而是客户/用户的需求。如果您的低效代码“完成工作”并且您可以找到可以轻松处理它的服务器,则无需增强代码,除非您遇到资源不足的情况。
  • 从我发现它不够不区分大小写但现在我想它可能是早期代码的挂起。所以我现在可能可以调整查询了。
【解决方案2】:

与许多其他问题一样,直接的方法也无济于事。
由 5500 行组成的 HTML 页面总是效率低下且速度缓慢。令人难以置信的低效和非常缓慢。

因此,您不需要一些狡猾的算法,而是完全不同的架构。

分页是你需要的。

将您的列表拆分为页面。

【讨论】:

  • 是的,这总是一个解决方案,但不是我的主要目标。我想要的就是一击即中……ink361.com/#/photos/133115598501394804_9688917
  • @Mark 如果您希望这样做,请使用 AJAX。首先,显示所有专辑,当用户点击任何专辑时,向服务器请求,为该专辑带来曲目和信息。
  • 啊,是的,这可能是一个不错的解决方案。因为最初的专辑视图实际上是几秒钟。 打开 AJAX 书籍
  • 通过将upper(album) 添加到主专辑查询来解决排序问题。不知道为什么我事先没有想到...
【解决方案3】:

您可以先flip the array 稍后检查密钥是否存在。这会比以前的迭代搜​​索快得多,因为它的索引搜索不同。

$flipped_$albumRow = array_flip($albumRow);
foreach($trackArray as $k => $v){
    if(isset($flipped_albumRow[$v['album']]))){ # <- line of interest.
        $list.="track html info";
    }
}

【讨论】:

  • 啊,这是一个更有建设性的帮助,而不是对代码的判断。谢谢!
  • 您不会相信这让整个过程变得如此之快。我将把它与 JOIN 结合起来(这可能意味着这将变得多余,但仍然是所有有用的学习!)
  • @Mark 地面信息基于此帖。 stackoverflow.com/questions/8826908/…
猜你喜欢
  • 2012-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-25
  • 2014-09-02
  • 1970-01-01
  • 2015-10-01
  • 2015-06-14
相关资源
最近更新 更多