3

我有 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 内存吗?我需要一种减少内存使用的方法

提前致谢

4

3 回答 3

3

12 个查询?请注意,UNIONSQL. 试试这个:

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
于 2012-11-28T08:35:47.397 回答
1

全部在查询中。下面的查询将为您提供每个国家、用户类型和包的计数结果。显然,您可以使用循环来创建 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]++;

最后,如果您使用像您这样的多维数组,则在内部必须进行大量检查。简单地说,它会首先在数组中找到正确的国家,这将给出另一个数组。它将在该数组中找到用户类型,然后在第三个数组中再次执行相同的操作。

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

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

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

于 2012-11-28T08:50:06.463 回答
1

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

您需要在 while 循环结束时取消设置行、国家、用户类型和包。这应该有助于记忆(至少在 PHP 5.3 之前,我在遍历大量数据行时遇到了类似的问题)。另一个问题是 stat_arr 变量,因为它为数据库中 3 个字段的每个组合创建 1 个数组字段。最坏的情况是您有 200k 个条目。这本身会占用很多内存。

此外,据我所知,您只想计算这 3 个列。这可以以不同的方式完成:

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

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

这样您就不必手动汇总它们,而是可以通过 SQL 来完成(大多数时候效率更高)。

于 2012-11-28T08:33:03.220 回答