2011-01-20 90 views
1

我有一个MySQL表像这样的:帮助需要优化的MySQL SELECT查询

day  int(11) 
hour int(11)  
amount int(11) 

日是用从0跨越至365的值的整数,假设小时是一个时间戳和量仅仅是一个简单整数。我想要做的是选择金额字段的值为特定的一组天数(例如从0到10),但我只需要当天可用金额的最后一个值,这实际上是小时字段有其最大值(当天内)。这听起来不太难,但我提出的解决方案完全没有效率。

这就是:

SELECT q.day, q.amount 
    FROM amt_table q 
    WHERE q.day >= 0 AND q.day <= 4 AND q.hour = (
     SELECT MAX(p.hour) FROM amt_table p WHERE p.day = q.day 
    ) GROUP BY day 

它需要5秒钟执行一个11K行表查询,它只是需要5天的跨度;我可能需要选择整个月份或年份的跨度,因此这不是有效的解决方案。如果需要的话

如果谁可以帮我找到另一种解决方案或优化这个人是真的感谢

编辑

没有指标设定,但(日,小时,量)可能是一个PRIMARY KEY

+1

设置了哪些索引?无论如何,请发表您的表CREATE语句(或架构转储) - 它会让人们更容易提出建议。 – 2011-01-20 23:27:06

+0

实际上没有设置索引,因为我不知道如何正确设置它们来帮助整体性能。无论如何,正如我所说(日,小时,金额)可能是主键 – 2011-01-20 23:32:57

回答

4

用途:

SELECT a.day, 
     a.amount 
    FROM AMT_TABLE a 
    JOIN (SELECT t.day, 
       MAX(t.hour) AS max_hour 
      FROM AMT_TABLE t 
     GROUP BY t.day) b ON b.day = a.day 
         AND b.max_hour = a.hour 
WHERE a.day BETWEEN 0 AND 4 

我认为你正在使用GROUP BY a.day只是为了得到尽可能每天一笔金额,但它不可靠,因为在MySQL中,不在GROUP BY中的列是任意的 - 值可能会改变。可悲的是,MySQL还不支持分析(ROW_NUMBER等),这是您通常用于这些情况的分析。

首先查看主键上的索引,然后在用于将表连接在一起的列上添加索引。合成索引(多个列到索引)也是一个选项。

0

我认为问题是where子句中的子查询。 MySQl首先会为整个表格计算这个“SELECT MAX(p.hour)FROM amt_table p WHERE p.day = q.day”,然后选择日期。效率不高:-)