1

我必须为我的应用程序做一些统计,所以我需要一个性能尽可能好的算法。我有几个问题。

我在mysql数据库中有这样的数据结构:

user_id    group_id     date
1          5            2012-11-20
1          2            2012-11-01
1          4            2012-11-01
1          3            2012-10-15
1          9            2013-01-18
...

所以我需要在特定日期找到某个用户的组。例如,用户 1 在日期 2012-11-15(2012 年 11 月 15 日)的组应返回最近的组,即 2012-11-01 日期的 2 和 4(同时有多个组)(最接近和更小的日期)。

通常,我可以执行 Select where date <= selected date order by date desc 等...但这不是重点,因为如果我有 1000 个用户,则需要 1000 个请求才能获得所有结果。

所以这里有一些问题:

  1. 我已经使用php的方法循环数组以避免大量的mysql请求,但是仍然不好,因为数组大小可能是10000+。使用 foreach(或 for?)非常昂贵。所以我的问题是,如果给定一个按日期(desc 或 asc)排序的数组,找到包含小于(或大于)给定日期的日期的元素的最近索引的最快方法是什么?除了使用 for 或 foreach 循环来遍历每个元素。
  2. 如果第一个问题没有解决方案,那么对于这类问题你会建议什么样的数据结构。

注意:日期为mysql格式,存储在数组中时不转换为时间戳

编辑:这是一个 sql fiddle http://sqlfiddle.com/#!2/dc28d/1 对于dos_id = 6, t="2012-11-01"它应该只返回2 和 5在日期“2010-12- 10 13:16:58"

4

2 回答 2

2

不知道为什么要在 php.ini 中执行此操作。这里有一些 SQL 使用连接来获取给定日期的所有用户的最新组。确保您有日期和用户 ID 的索引。

SELECT *
FROM test t1
LEFT JOIN test t2
ON t1.userid = t2.userid AND t2.thedate <= '2012-11-15' AND t2.thedate > t1.thedate
WHERE t1.thedate <= '2012-11-15' AND t2.userid IS NULL;

SQLfiddle

或者使用你的 SQLFiddle

SELECT t1.*
FROM dossier_dans_groupe t1
LEFT JOIN dossier_dans_groupe t2
ON t1.dos_id = t2.dos_id AND t2.updated_at <= '2012-11-01' 
   AND t2.updated_at > t1.updated_at
WHERE t1.updated_at <= '2012-11-01' AND t2.dos_id IS NULL;
于 2013-02-04T10:20:24.500 回答
1

这将为您提供所有用户及其组的列表(每组 1 行),其最新日期小于您指定的日期(以下 2012 年 11 月 15 日)。

SELECT user_id, group_id, date FROM table WHERE date <= '2012-11-15' AND NOT EXISTS (SELECT 1 FROM table test WHERE test.user_id = table.user_id AND test.date > table.date and test.date <= '2012-11-15')
于 2013-02-04T10:00:35.217 回答