首先,我所知道的关于mySql的一切都是自学的,所以如果有什么我做错了或效率低下,请告诉我。我有一个30多列的表,看起来像这样...(忽略实际值,这只是想知道表是什么样的)
id | uid | c1 | c2 | c3 |..cols 4-29...| c30 | time
---------------------------------------------------------------
1 | 15 | 234 | 11 | 21 | | 18 | 2013-01-19 00:00:00
2 | 96 | 311 | 29 | 23 | | 27 | 2013-01-19 00:00:00
3 | 13 | 443 | 31 | 33 | | 35 | 2013-01-19 00:00:00
4 | 97 | 345 | 44 | 47 | | 48 | 2013-01-19 00:00:00
5 | 85 | 271 | 53 | 49 | | 52 | 2013-01-19 00:00:00
6 | 96 | 273 | 62 | 50 | | 64 | 2013-01-20 00:00:00
7 | 13 | 449 | 54 | 57 | | 87 | 2013-01-20 00:00:00
8 | 97 | 374 | 93 | 59 | | 62 | 2013-01-20 00:00:00
9 | 85 | 851 | 71 | 87 | | 74 | 2013-01-20 00:00:00
id
是主键; uid
也被编入索引 - 它是每个用户的id值,与另一个名为user_names
的表中的用户名相匹配。然后有30列数据和一个时间戳字段。
每天都会使用每个用户的新值更新表格。我需要为每列选择一段时间内最大的差异,以及每列的增益名称。我有一些有用的查询,但它们很慢并且看起来非常低效。例如:
SELECT tbl1.name as col1_name, tbl1.col1_diff,
tbl2.name as col2_name, tbl2.col2_diff FROM
(SELECT pl.name, (MAX(c1)-MIN(c1)) as col1_diff FROM
`data_table` tbl JOIN `user_names` as pl ON tbl.pid=pl.id
WHERE time BETWEEN '2013-06-05 00:00:00' AND '2013-06-06 00:00:00'
GROUP BY pid ORDER BY col1_diff DESC LIMIT 1) as tbl1
JOIN (SELECT pl.name, (MAX(c2)-MIN(c2)) as col2_diff FROM
`data_table` tbl JOIN `user_names` as pl ON tbl.pid=pl.id
WHERE time BETWEEN '2013-06-05 00:00:00' AND '2013-06-06 00:00:00'
GROUP BY pid ORDER BY col2_diff DESC LIMIT 1) as tbl2
只为前两列提取正确的数据,例如:
col1_name | col1_diff | col2_name | col2_diff
------------------------------------------------
josh | 4124 | steve | 512
虽然我更喜欢为每列而不是一个总结果行获得1行,但我至少可以使用它。但是这个查询已经需要大约0.5秒,并且我添加的每个连接计算另一个列只会增加到那个时间,从而导致不可接受的查询时间。
我正在寻找尽可能快地提取这些数据的方法。我知道每个派生表中的用户名加入肯定会减慢我的速度,但我无法想出一种方法来在最后用一个大连接拉出每个单独的名称(如果这甚至是接近它的方式?)。我已经尝试快速编写1个查询来为每行提取数据并循环30次,但这很慢,对我来说效率似乎更低。我已经考虑过在每天结束时计算每个人的收益并将它们存储在一个单独的表中,但我觉得必须有一个更好的解决方案。
最终显示此数据的页面需要显示每个列的最高获取用户及其增益,但我需要使用不同的日期范围(昨天,过去7天和过去30天)运行查询3次;任何有关最佳方法的帮助或想法都非常感谢。