【问题标题】:PHP - MySQL to PDOPHP - MySQL 到 PDO
【发布时间】:2015-07-07 02:02:32
【问题描述】:

所以我最终决定改用 PDO 而不是使用旧的 mysql_

但我注意到我的网站加载速度较慢。这是一个有 500 行的表,我的 mysql_ 查询加载速度稍快(快 0.5-1 秒)。

我想知道这只是 PDO 的工作方式,还是我在某个地方犯了一些错误。我从 MySQL 到 PDO 并没有太大变化。

这是我原来的mysql_代码:

<?php
                    $sql = mysql_query("SELECT * FROM rookstayers ORDER BY level DESC LIMIT 0, 500");
                    $id = 1;
                    $last_player_lvl = '';

                    while($row = mysql_fetch_array($sql)){
                        $name = $row['name'];
                        $level = $row['level'];
                        $world = $row['world'];
                        $account = $row['accountstatus'];
                        $status = $row['onlinestatus'];
                        $country = $row['country'];
                        $lastlogindate = $row['lastlogin'];
                        $lastlogin2 = utf8_decode($lastlogindate);
                        $lastlogin = str_replace("?", " ", $lastlogin2);
                        $onrow = '';
                        $typeServ = '';

                        $Date = $lastlogin;
                        $Date = substr($Date, 0, strpos($Date, " CE"));
                        $now  = date('Y-m-d');
                        $datetime1 = new DateTime($Date);
                        $datetime2 = new DateTime($now);
                        $interval = $datetime1->diff($datetime2);

                        $difference = $interval->format('%a days ago');

                        $player_name = urlencode($name);

                        if ($status == 1){
                            $status = 'Online';
                            $onrow = 'online';
                        } else {
                            $status = 'Offline';
                            $onrow = 'offline';
                        }

                        if ($account == 'Premium Account'){
                            $account = 'Premium';
                        } else {
                            $account = 'Free';
                        }

                        if ($world == 'Aurora' || $world == 'Aurera'){
                            $typeServ = 'activer';
                        } else {
                            $typeServ = '';
                        }

                    echo "<tr class=" . $typeServ . ">";
                        echo "<td align='right'>" . ( ($last_player_lvl == $row['level']) ? '' : $id ) . "</td>";
                        echo "<td align='center'><img src='../img/flags/" . $country . ".gif'></td>";
                        echo "<td><div class='". $onrow ."'></div></td>";
                        echo "<td><a href='../char/" . $player_name . "' class='playerlink'>" . $name . "</a></td>";
                        echo "<td>" . $level . "</td>";
                        echo "<td><a href='../world/" . $world ."' class='worldlink'>" . $world . "</a></td>";
                        echo "<td>"; if ($difference == 0){ echo "Today"; } elseif($difference == 1) { echo "Yesterday"; } else { echo $difference; } echo "</td>";
                        echo "<td>" . $account . "</td>";
                    echo "</tr>";

                    // Check if there are duplicate levels, if so, give them the same rank
                    if($last_player_lvl == $row['level']){
                        $id = $id;
                    }else{
                        $id++;
                    }

                    $last_player_lvl = $row['level'];
                }
                echo "</tbody>";
            echo "</table>";
            ?>

这是我的 PDO 代码

<?php

                $sql = 'SELECT * FROM rookstayers ORDER BY level DESC LIMIT 0, 500';
                $id = 1;
                $last_player_lvl = '';

                foreach ($db->query($sql) as $row) {
                    $name = $row['name'];
                    $level = $row['level'];
                    $world = $row['world'];
                    $account = $row['accountstatus'];
                    $status = $row['onlinestatus'];
                    $country = $row['country'];
                    $lastlogindate = $row['lastlogin'];
                    $lastlogin2 = utf8_decode($lastlogindate);
                    $lastlogin = str_replace("?", " ", $lastlogin2);
                    $onrow = '';
                    $typeServ = '';

                    $Date = $lastlogin;
                    $Date = substr($Date, 0, strpos($Date, " CE"));
                    $now  = date('Y-m-d');
                    $datetime1 = new DateTime($Date);
                    $datetime2 = new DateTime($now);
                    $interval = $datetime1->diff($datetime2);

                    $difference = $interval->format('%a days ago');

                    $player_name = urlencode($name);

                    if ($status == 1){
                        $status = 'Online';
                        $onrow = 'online';
                    } else {
                        $status = 'Offline';
                        $onrow = 'offline';
                    }

                    if ($account == 'Premium Account'){
                        $account = 'Premium';
                    } else {
                        $account = 'Free';
                    }

                    if ($world == 'Aurora' || $world == 'Aurera'){
                        $typeServ = 'activer';
                    } else {
                        $typeServ = '';
                    }

                    echo "<tr class=" . $typeServ . ">";
                    echo "<td align='right'>" . ( ($last_player_lvl == $row['level']) ? '' : $id ) . "</td>";
                    echo "<td align='center'><img src='../img/flags/" . $country . ".gif'></td>";
                    echo "<td><div class='". $onrow ."'></div></td>";
                    echo "<td><a href='../char/" . $player_name . "' class='playerlink'>" . $name . "</a></td>";
                    echo "<td>" . $level . "</td>";
                    echo "<td><a href='../world/" . $world ."' class='worldlink'>" . $world . "</a></td>";
                    echo "<td>"; if ($difference == 0){ echo "Today"; } elseif($difference == 1) { echo "Yesterday"; } else { echo $difference; } echo "</td>";
                    echo "<td>" . $account . "</td>";
                    echo "</tr>";

                    // Check if there are duplicate levels, if so, give them the same rank
                    if($last_player_lvl == $row['level']){
                        $id = $id;
                    }else{
                        $id++;
                    }

                    $last_player_lvl = $row['level'];
                }
                echo "</tbody>";
                echo "</table>";
                ?>

PDO 部分有什么需要改进的地方吗?

【问题讨论】:

  • 尝试为“级别”创建一个索引,它可能会提高您的查询速度。
  • 索引?顺便说一句,这是我的数据库的样子:i.imgur.com/PJKx2QQ.png@Mindastic
  • 是的,比如“ALTER TABLE rookstayer ADD INDEX(level);”

标签: php mysql sql database pdo


【解决方案1】:

您正在 foreach 循环的每次迭代中执行查询。 查看更新。

尝试替换

foreach ($db->query($sql) as $row) { ...

$result = $db->query($sql);
foreach ($result as $row) {

更新:@mario 是对的。 foreach 不会在每次迭代时评估表达式。我似乎找不到关于为什么这会解决 OPs 问题的结论性答案;我仍然认为它有一些东西,但即使在我自己的测试中,使用该变量似乎对性能没有任何显着影响。如果有人有更多细节要补充,请补充。 :)

【讨论】:

  • 我认为这应该是正确的答案,因为您使用的是对数据的引用,而不是不断地重复相同的数据。 +1
  • 就是这样!谢谢!我知道这是关于查询的事情,但我不确定是什么,第一次使用 PDO,我通常也是 PHP 的新手,呵呵。非常感谢!大大提高了速度!
  • 等等。什么?为什么foreach 会对表达式求值两次?如果每次都得到一个新的Traversable,它怎么能跑过结果呢?如果它确实重新运行了查询,它不会成为每个结果行的无休止循环吗? (不,我不认为 OP 的观察性能结论是可信的。)
猜你喜欢
  • 2016-10-01
  • 1970-01-01
  • 2011-02-18
  • 1970-01-01
  • 2013-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多