开发者

Help needed optimizing MySQL SELECT query

I have a MySQL table like this one:

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

Day is an integer with a value that spans from 0 to 365, assume hour is a timestamp and amount is just a simple integer. What I want to do is to select the value of the amount field for a certain group of days (for example from 0 to 10) but I only need the last value of amount available for that day, which pratically is where the hour field ha开发者_运维技巧s its max value (inside that day). This doesn't sound too hard but the solution I came up with is completely inefficient.

Here it is:

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

It takes 5 seconds to execute that query on a 11k rows table, and it just takes a span of 5 days; I may need to select a span of en entire month or year so this is not a valid solution.

Anybody who can help me find another solution or optimize this one is really appreciated

EDIT

No indexes are set, but (day, hour, amount) could be a PRIMARY KEY if needed


Use:

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

I think you're using the GROUP BY a.day just to get a single amount value per day, but it's not reliable because in MySQL, columns not in the GROUP BY are arbitrary -- the value could change. Sadly, MySQL doesn't yet support analytics (ROW_NUMBER, etc) which is what you'd typically use for cases like these.

Look at indexes on the primary keys first, then add indexes on the columns used to join tables together. Composite indexes (more than one column to an index) are an option too.


I think the problem is the subquery in the where clause. MySQl will at first calculate this "SELECT MAX(p.hour) FROM amt_table p WHERE p.day = q.day" for the whole table and afterwards select the days. Not quite efficient :-)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜