使用php优化多周的mysql查询

时间:2013-07-16 15:14:47

标签: php mysql sql database optimization

我有一个脚本,用于查询50,000条记录的数据库,并尝试创建一个表,概述每周向数据库中输入的新条目的每周报告。

我有一个约束:报告必须从$START_DATE开始,这是网站每个部分下数据库中任何用户都有记录的第一天。这意味着我不能使用查找预定义日期的函数,我必须在第一个用户输入数据库的第一秒限制的部分中计算用户,直到一周之后,直到$END_DATE为止。通常只是time()

查询数据库以查找count(*)select *

大约需要5秒钟
mysql> select count(*), user_type from users_table where user_permissions = "normal" group by user_type;
+----------+-----------------+
| count(*) | user_type       |
+----------+-----------------+
|     2210 | myspace_user    | 
|    48659 | facebook_user   | 
+----------+-----------------+
2 rows in set (4.73 sec)

我有一些PHP代码,每个user_type查询数据库一次,以获得每周报告的详细表格。问题是,有12周和两种用户类型,因此整个过程最多需要两分钟。该站点的某些部分有两种以上的用户类型,这些查询需要更长时间。这是代码:

$start = strtotime($START_DATE);
$end = strtotime($END_DATE);
for ($i = 0; $start+$i < time() && $start+$i < $end; $i+= (7*24*60*60)) {
    $weekly_total = 0;
    foreach($USERTYPES as $usertype) {
        $q = "select count(*) from users_table where user_type = '" . $usertype . "' and user_permissions = 'normal'";
        $q .= " and UNIX_TIMESTAMP(timestmp) >= " . strval($start+$i) . " and UNIX_TIMESTAMP(timestmp) <= " . strval($start+$i+(7*24*60*60));
        $r = mysql_query($q);
        $v = mysql_fetch_array($r);
        $table['weekly'][gmdate("Y-m-d", $start+$i)][$usertype] += $v[0];
        $weekly_total += $v[0];
    }
    $table['weekly'][gmdate("Y-m-d", $start+$i)]['weekly_total'] = $weekly_total;
}

最后,我有一个包含12个条目的数组,其基本结构最终像这个伪代码一样:

// ...previous entries
$table['weekly']['2013-07-01'] = array(
    'myspace_user' => 123,
    'facebook_user' => 1234,
    'weekly_total' => 1357
);
$table['weekly']['2013-07-08'] = array(
// ...and so on

生成这些查询并将其保存到表中的过程耗时太长。有没有什么方法可以使MySQL或PHP函数更高效,所以我不必为每周生成一个单独的查询?

1 个答案:

答案 0 :(得分:0)

您的代码非常低效,在围栏两侧(PHP和MySQL)强制进行多个日期 - >时间戳转换。为什么没有更简单的

$start = '2013-07-16';

for ($week = 0; $week < 52; $week++) {
    SELECT ...
    ...
    WHERE timestmp BETWEEN ($start + INTERVAL $week WEEK)
        AND ($start + INTERVAL $week WEEK + INTERVAL 7 DAY)
}

您将坚持使用本机MySQL日期时间值,而不需要重复本机 - >&gt; int-&gt; native-&gt;无论转换如何。