2011-08-03 45 views
0

前奏曲:我有一个大型数据集,其中有数十万条记录存储在MySQL数据库中。大大简化了,每行都有一个日期时间字段来存储打电话的日期和时间,以及一个整数字段来存储呼叫的长度。PHP中的日期匹配和插值


方案:我忙着写在PHP的内插函数,它产生一系列由预先计算的间隔所分离的日期。每个生成的日期都存储在一个关联数组中,并将日期用作键,并将每个值初始化为0.然后,脚本向数据库查询记录列表,并尝试将日期时间记录与预定义日期中的最近日期进行匹配,生成关联数组。当找到最接近的匹配时,它只是将呼叫持续时间添加到该索引处数组的现有值。所生成的关联数组


实施例:

$array = array( "2011-01-01 09:00:00" => 0, 
         "2011-01-01 09:30:00" => 0, 
         "2011-01-01 10:00:00" => 0, 
         "2011-01-01 10:30:00" => 0, 
         "2011-01-01 11:00:00" => 0, 
         "2011-01-01 11:30:00" => 0, 
         "2011-01-01 12:00:00" => 0 
        ) 

在上述例子中,使用30分钟的间隔中产生日期范围。


的从MySQL数据库中的记录例:

+---------------------+----------+ 
| datetime   | duration | 
+---------------------+----------+ 
| 2011-01-01 09:02:26 |  1 | 
| 2011-01-01 09:14:51 |  1 | 
| 2011-01-01 10:40:33 |  549 | 
| 2011-01-01 11:10:27 |  38 | 
| 2011-01-01 11:31:50 |  82 | 
+---------------------+----------+ 

每个这些记录现在需要匹配于从上面给出的预先产生的阵列最接近日期时间键和添加的duration值到现有的匹配值。


问题: 这是很容易构建两个嵌套for遍历从数据库中记录interate然后线性通过关联数组运行找到匹配,但这是效率非常低,并且成为问题对于大数据集(想想bubblesort,这就是大致等价的)。稍微好一点的方法是线性循环来自数据库的记录,然后将数组作为二叉树遍历,这当然更有效,并且可能是因为两个数组按时间顺序排序。


问题: 是否有处理比我怎么在上述问题中描述这个日期匹配更有效的方式?

+0

如果两个列表均按日期/时间排序,则可以使用合并。像mergesort一样:http://en.wikipedia.org/wiki/Merge_sort – Erik

回答

3

那么将日期的UNIX_TIMESTAMP()除以30 * 60秒(30分钟),并使用ROUND()作为整数。然后,使用GROUP BY对它们进行分组,最后使用SUM()来计算持续时间。

SELECT SUM(duration), ROUND(UNIX_TIMESTAMP(datetime)/(30 * 60)) FROM table GROUP BY ROUND(UNIX_TIMESTAMP(datetime)/(30 * 60)) 
+0

虽然我没有这样做,但我仍然接受你的答案,因为它给了我一个工作的基础。我的实现在PHP中,并对您的建议执行类似的计算。 –

1

您当前的算法(如果我理解正确的话)是这样的:

  1. 获取所有记录
  2. 每条记录​​的日期时间进行比较,以数组键
  3. Incremement的总和基于记录的适当阵列值

更有效的方法可以是:

  1. 查询的持续时间为给定时间的子集相匹配
  2. 插入的总和与合适的密钥

这允许MySQL来提供优化的数学逻辑和阵列中的所有记录的总和减少脚本所需的数组迭代次数。您将增加数据库查询的数量,但基准测试会告诉您折衷是否值得。