使用存储的查询搜索大(600万)行MySQL?

时间:2016-08-28 15:19:53

标签: mysql highcharts

我有一个包含大约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的密钥。

2 个答案:

答案 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;