首先,我对 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
这仅提取前 2 列的正确数据,例如:
col1_name | col1_diff | col2_name | col2_diff
------------------------------------------------
josh | 4124 | steve | 512
虽然我更喜欢为每一列而不是一个总结果行获得 1 行,但我至少可以使用它。但是这个查询已经花费了大约 0.5 秒,而且我为计算另一列而添加的每个连接只会增加该时间,从而导致查询时间不可接受。
我正在寻找尽可能快地提取这些数据的方法。我知道每个派生表中的用户名连接肯定会让我放慢速度,但我无法想出一种方法来拉每个单独的名称,最后用一个大连接(如果这甚至是接近它的方法吗?)。我已经尝试快速编写 1 个查询来提取每一行的数据并循环 30 次,但这很慢,而且对我来说似乎效率更低。我考虑过在一天结束时计算每个人的收益并将它们存储在单独的表中,但我觉得必须有更好的解决方案。
最终将显示此数据的页面需要显示每列获得最多的用户及其收益,但我需要使用不同的日期范围(昨天、过去 7 天和过去 30 天)运行 3 次查询;非常感谢您对解决此问题的最佳方法的任何帮助或想法。