我有一个包含大约600万个条目的数据库 - 并且还会增长 - 我正在运行查询以返回HighCharts图表功能。我需要多年纵向阅读,所以我正在运行这样的查询:
foreach($states as $state_id) { //php code
SELECT //mysql psuedocode
sum(case when mydatabase.Year = '2003' then 1 else 0 end) Year_2003,
sum(case when mydatabase.Year = '2004' then 1 else 0 end) Year_2004,
sum(case when mydatabase.Year = '2005' then 1 else 0 end) Year_2005,
sum(case when mydatabase.Year = '2006' then 1 else 0 end) Year_2006,
sum(case when mydatabase.Year = '2007' then 1 else 0 end) Year_2007,
sum(case when mydatabase.Year = '$more_years' then 1 else 0 end) Year_$whatever_year,
FROM mytable
WHERE State='$state_id'
AND Sex IN (0,1)
AND Age_segment IN (5,4,3,2,1)
AND "other_filters IN (etc, etc, etc)
} //end php code
但是对于各种状态一次......所以返回让我们说5个状态,每个状态都有上面的语句,但状态ID被替换。同时,这些年份可以是任意年份,性别(男/女/其他)和年龄段以及其他修饰符会根据过滤器不断变化。查询很长(至少30-40秒)一块。所以我有一个想法 - 除非我完全做错了 - 实际上是将上面的查询存储在带有结果的第二个表中,并首先检查"元查询"并查看它是否已被缓存"然后返回结果而不读取数据库(不经常更新)。
这是一个好方法还是我没有看到潜在的问题?
编辑:改为表,而不是db(duh)。
表结构是:
id | Year | Sex | Age_segment | Another_filter | Etc
没有什么比这更复杂,也没有加入任何其他东西。现在有id,Year,Sex和Age_segment的密钥。
答案 0 :(得分:1)
伪代码......
SELECT Year
, COUNT(*) total
FROM my_its_not_a_database_its_a_table
WHERE State = $state_id
AND Sex IN (0,1)
AND Age_segment IN (5,4,3,2,1)
GROUP
BY Year;
答案 1 :(得分:1)
正确的索引是加速查询所需的。首先对查询执行“EXPLAIN”并在此处发布结果。
我建议以下内容开始。这样可以避免for循环并在1个查询中返回数据。不知道每列的行数和基数我建议使用State和Year的综合索引。
SELECT mytable.State,mytable.Year,count(*)
FROM mytable
AND Sex IN (0,1)
AND Age_segment IN (5,4,3,2,1)
AND "other_filters IN (etc, etc, etc)
GROUP BY mytable.State,mytable.Year
通过检查某些列的基数,可以进一步优化上述查询。运行以下命令以获得基数:
SELECT Age_segment FROM mytable GROUP BY Age_segment;