2014-11-22 63 views
2

我是MySQL的新手,我試圖優化下面的查詢和/或表。非常感謝您提供更高效的幫助和解釋。優化MySQL查詢/表百萬+行

查詢:

SELECT SQL_CACHE 
nick as viewer, 
CONVERT(rank, UNSIGNED) as rank, 
CONVERT(FLOOR(amount), UNSIGNED) as amount 
FROM (
     SELECT @rank:[email protected]+1 AS rank, 
     nick, 
     amount 
     FROM (
      SELECT nick, 
      SUM(amount) as amount 
      FROM points_log WHERE dt >= NOW()-INTERVAL 1 hour 
      GROUP BY nick 
      ) as t1, 
    (SELECT @rank := 0) t2 
    ORDER BY amount DESC 
    ) as t3 
WHERE nick='PrestonConnors'; 

輸出:

+----------------+------+--------+ 
| viewer   | rank | amount | 
+----------------+------+--------+ 
| prestonconnors | 521 |  13 | 
+----------------+------+--------+ 
1 row in set (1.73 sec) 

這裏是從查詢解釋輸出:

+----+-------------+------------+--------+---------------+----------+---------+------+--- -----+----------------+ 
| id | select_type | table  | type | possible_keys | key  | key_len | ref | rows | Extra   | 
+----+-------------+------------+--------+---------------+----------+---------+------+--------+----------------+ 
| 1 | PRIMARY  | <derived2> | ALL | NULL   | NULL  | NULL | NULL | 5408 | Using where | 
| 2 | DERIVED  | <derived4> | system | NULL   | NULL  | NULL | NULL |  1 | Using filesort | 
| 2 | DERIVED  | <derived3> | ALL | NULL   | NULL  | NULL | NULL | 5408 |    | 
| 4 | DERIVED  | NULL  | NULL | NULL   | NULL  | NULL | NULL | NULL | No tables used | 
| 3 | DERIVED  | points_log | index | dt_idx  | nick_idx | 25  | NULL | 784143 | Using where | 
+----+-------------+------------+--------+---------------+----------+---------+------+--------+----------------+ 

下面是表:

CREATE TABLE `points_log` (
    `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, 
    `nick` char(25) NOT NULL, 
    `amount` decimal(8,4) NOT NULL, 
    `stream_online` tinyint(1) NOT NULL, 
    `modification_type` tinyint(3) unsigned NOT NULL, 
    `dt` datetime NOT NULL, 
    PRIMARY KEY (`id`,`dt`,`nick`), 
    KEY `nick_idx` (`nick`), 
    KEY `amount_idx` (`amount`), 
    KEY `modification_type_idx` (`modification_type`), 
    KEY `dt_idx` (`dt`), 
    KEY `stream_online_idx` (`stream_online`) 
) ENGINE=InnoDB AUTO_INCREMENT=866040 DEFAULT CHARSET=latin1 
/*!50100 PARTITION BY RANGE (YEAR(dt)) 
SUBPARTITION BY HASH (MONTH(dt)) 
SUBPARTITIONS 12 
(PARTITION p0 VALUES LESS THAN (2014) ENGINE = InnoDB, 
PARTITION p1 VALUES LESS THAN (2015) ENGINE = InnoDB, 
PARTITION p3 VALUES LESS THAN MAXVALUE ENGINE = InnoDB) 
+0

我不認爲你需要這些CONVERT,單個子查詢也沒關係。 – Mihai 2014-11-22 01:20:35

回答

1

,我能想到的唯一的事情是在索引:

points_log(dt, nick, amount) 

如果你需要這樣的表現,你可能需要創建一個彙總表。必須使用觸發器總結整個表並維護彙總表。