最佳实践php数组和RAM使用

时间:2012-11-28 08:23:54

标签: php mysql arrays memory

我有12个mysql数据库表,如table1,table2,.... table12。每个表有200,000条记录。每条记录包括国家,用户类型,包列。我想获得3列以上的统计数据。要做到这一点,首先,我正在创建数组。然后使用数组,我得到统计数据。

for ($i=1; $i<=12; $i++)
{
   $query="SELECT `country`, `usertype`, `package` FROM `table$i`";
   $result=mysql_query($query);
   while ($row = mysql_fetch_assoc($result))
   {
      $country= $row['country'];
      $usertype= $row['usertype'];
      $package= $row['package'];

      $stat_array[$country][$usertype][$package]= 1 + $stat_array[$country][$usertype][$package]
   }
}

获得结果需要很多时间。这是获得统计数据的最佳方式吗?请指教我一个好方法。此外,这将使用更多的RAM内存。我需要一种方法来减少内存使用

提前致谢

3 个答案:

答案 0 :(得分:3)

12个查询?请注意,UNION中有SQL命令。 试试这个:

for ($i=1; $i<=12; $i++)
   $query=($i>1?'UNION ALL ':'')."SELECT `country`, `usertype`, `package` FROM `table$i` ";
$result=mysql_query($query);
// other code below

答案 1 :(得分:1)

这里的一个问题是因为你们都在同一个函数中,php不会删除变量分配的内存。因此,您覆盖/创建一个新行,....

您需要在while循环结束时取消设置row,country,usertype和package。这应该有助于记忆(至少直到PHP 5.3,我在迭代数据行的大量数据时遇到了类似的问题)。另一个问题是stat_arr变量,因为它为数据库中3个字段的每个组合创建了1个数组字段。最坏的情况是你有200k的条目。这本身就会占用很多公羊。

此外,从我看到的你只想数这3个coloumns。可以采用不同的方式:

使用(我不知道您如何调用您的ID /主要字段,因此我在以下代码中将其称为id):

$Query = "SELECT count(id) AS c_u_p_statistics,`country`, `usertype`, `package` FROM `table$i` GROUP BY `country`, `usertype`, `package`";

这样你就不必手动总结它们,但可以通过SQL(大部分时间效率更高)来实现。

答案 2 :(得分:1)

全部在查询中。下面的查询将为您提供每个国家/地区的计数,usertype和包的结果。显然你可以使用一个循环来创建12个表联合,但为了便于阅读,我把它写下来了。

还要记住使用UNION ALL而不仅仅是UNION。如果你使用UNION重复的行将被丢弃,但如果表1的某个组的计数为100,而表2的同一组也有100,则要返回100两次,因此总和为200.如果你使用UNION它将返回100次,总和显然也是100。

SELECT SUM(cnt) as total, `country`, `usertype`, `package` FROM
(
    SELECT COUNT(country) as cnt, `country`, `usertype`, `package` FROM table1 GROUP BY `country`, `usertype`, `package`
    UNION ALL
    SELECT COUNT(country) as cnt, `country`, `usertype`, `package` FROM table2 GROUP BY `country`, `usertype`, `package`
    UNION ALL
    SELECT COUNT(country) as cnt, `country`, `usertype`, `package` FROM table3 GROUP BY `country`, `usertype`, `package`
    UNION ALL
    SELECT COUNT(country) as cnt, `country`, `usertype`, `package` FROM table4 GROUP BY `country`, `usertype`, `package`
    UNION ALL
    SELECT COUNT(country) as cnt, `country`, `usertype`, `package` FROM table5 GROUP BY `country`, `usertype`, `package`
    UNION ALL
    SELECT COUNT(country) as cnt, `country`, `usertype`, `package` FROM table6 GROUP BY `country`, `usertype`, `package`
    UNION ALL
    SELECT COUNT(country) as cnt, `country`, `usertype`, `package` FROM table7 GROUP BY `country`, `usertype`, `package`
    UNION ALL
    SELECT COUNT(country) as cnt, `country`, `usertype`, `package` FROM table8 GROUP BY `country`, `usertype`, `package`
    UNION ALL
    SELECT COUNT(country) as cnt, `country`, `usertype`, `package` FROM table9 GROUP BY `country`, `usertype`, `package`
    UNION ALL
    SELECT COUNT(country) as cnt, `country`, `usertype`, `package` FROM table10 GROUP BY `country`, `usertype`, `package`
    UNION ALL
    SELECT COUNT(country) as cnt, `country`, `usertype`, `package` FROM table11 GROUP BY `country`, `usertype`, `package`
    UNION ALL
    SELECT COUNT(country) as cnt, `country`, `usertype`, `package` FROM table12 GROUP BY `country`, `usertype`, `package`

) temp
GROUP BY `country`, `usertype`, `package`

旁注:你没必要做

$stat_array[$country][$usertype][$package]= 1 + $stat_array[$country][$usertype][$package];

你可以这样做:

$stat_array[$country][$usertype][$package]++;

最后,如果你像你一样使用多维数组,那么它必须在内部进行大量检查。简单地说,它将首先在阵列中找到正确的国家,这将提供另一个阵列。它将在该数组中找到usertype,然后在第三个数组中再次执行相同的操作。

如果$ country,$ usertype和$ package都是字符串,你可以加入字符串并使用它。

$key = $country.'_'.$usertype.'_'.$package;
$stat_array[$key]++;

但我想这一切都取决于你将数据存储在数组中后要对数据做什么。如果它只是打印总计数,你甚至不需要数组,而是直接在查询结果循环中打印。