【问题标题】:Queries execute correctly, but performance isn't good查询正确执行,但性能不佳
【发布时间】:2013-01-15 22:30:42
【问题描述】:

我创建了一个每天收集信息的数据库。就像日历一样,数据库存储会员的每日金额。如果月份不匹配任何现有月份(M-Y),数据库将创建一个新的 html 月份表。我已经解决了这个问题,如下:

mysql_query("something goes here");
while(condition)
{
    mysql_query("something goes here")
    while(condition)
    {
        mysql_query("something goes here");
        while()
        {
            ....................
        }
        ........................
    }
}

当我发现这个算法时,它运行良好。但是,几天后,它给我的服务器带来了沉重的负担。然后我在 PHP 中尝试了相同的算法(但我不能这样做)。我怎样才能让它运行得更快? 代码如下:

        $q2=mysql_query("SELECT  a.member_id,a.dates,MONTH(dates) AS months,
                        YEAR(dates)AS years,sum(amount) as sums
                        FROM account AS a
                        left join member as m
                        on(a.member_id=m.member_id)
                        GROUP BY (SELECT EXTRACT(YEAR_MONTH FROM dates))
                        ORDER by dates DESC
        ");
        $k=0;
        while($data2=mysql_fetch_assoc($q2))
        {
            $months=$data2['months'];
            $years=$data2['years'];
            $daten = new DateTime($data2['dates']);

            print "<tr><th align='left'><b>".$daten->format('F-Y')."</b></th>";

            $q3=mysql_query("select * from member");

            while($data3=mysql_fetch_assoc($q3))
            {
                $id3=$data3['member_id'];
                $q4=mysql_query("
                                SELECT SUM(amount) AS total FROM account
                                WHERE member_id=$id3
                                AND month(dates)=$months
                                AND year(dates)=$years                              
                            ");
                while($data4=mysql_fetch_assoc($q4))
                {
                    $total=$data4['total'];

                    print "<td class='total'>".number_format($total)."</td>";
                }
            }
            print "<td class='total'><b>".$data2['sums']."</b></td></tr>";
            $k=$k+$data2['sums'];
        }

【问题讨论】:

  • 您可以在客户端的 mysql 查询中使用EXPLAIN 来查看执行计划并查看其是否按预期工作。您的查询可能缺少适当的索引。

标签: php mysql algorithm


【解决方案1】:

除其他外:

  • 您正在为第一个查询中的每一行运行查询 SELECT * FROM member。这个查询是独立于循环的,所以每次都运行一遍很浪费。

  • 对于来自SELECT * FROM member 查询的每个结果,您正在运行另一个 查询 (SELECT SUM(amount) AS total FROM account ...)。这个查询有几个问题:

    • 首先,可以使用GROUP BY 将此查询组合到上一个查询中,以避免必须为每个成员运行一个查询。比如:

      SELECT member_id, SUM(amount) AS total FROM account WHERE ... GROUP BY member_id

    • 其次,您使用的是MONTH(dates) = $months AND YEAR(dates) = $years。这是低效的,因为它强制服务器检查每一行;如果dates 上有适当的索引,则将其转换为dates 上的范围(例如dates BETWEEN '$year-$months-01' AND '$year-$months-31')会加快速度。

一般情况下:避免循环查询。生成页面所涉及的查询数量应尽可能地始终是一个很小的、几乎恒定的数字。它不应该随着您的数据而增长。

【讨论】:

    【解决方案2】:

    您是否在 MySQL 数据库中设置了适当的索引?这可能会导致巨大的性能差异。 http://dev.mysql.com/doc/refman/5.0/en/mysql-indexes.html

    【讨论】:

    • 当我创建表时,我设置了一个默认索引(在工作台默认值中),但接下来我不能使用它
    • 您应该阅读索引,通常仅设置默认值是不够的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多