0

这是我的查询,通过更改 limit 子句中的偏移量,获取 10 条记录需要 5 秒以上的时间。表包含 1200 万条记录。

SELECT device_id
    ,media_id
    ,limit1.play_date
    ,limit1.start_time
    ,limit1.end_time
    ,SUBTIME(limit1.end_time, limit1.start_time) AS playback_duration
FROM device_media_log
INNER JOIN (
    SELECT play_date
        ,start_time
        ,end_time
        ,device_media_id
    FROM device_media_log
    ORDER BY play_date DESC
        ,start_time DESC
        ,end_time DESC limit 0
        ,10
    ) AS limit1 ON device_media_log.device_media_id = limit1.device_media_id;

解释计划::

+----+-------------+------------------+--------+---------------+---------+---------+------------------------+---------+----------------+
| id | select_type | table            | type   | possible_keys | key     | key_len | ref                    | rows    | Extra          |
+----+-------------+------------------+--------+---------------+---------+---------+------------------------+---------+----------------+
|  1 | PRIMARY     | <derived2>       | ALL    | NULL          | NULL    | NULL    | NULL                   |      10 |                |
|  1 | PRIMARY     | device_media_log | eq_ref | PRIMARY       | PRIMARY | 8       | limit1.device_media_id |       1 |                |
|  2 | DERIVED     | device_media_log | ALL    | NULL          | NULL    | NULL    | NULL                   | 8345645 | Using filesort |
+----+-------------+------------------+--------+---------------+---------+---------+------------------------+---------+----------------+

这是创建表::

CREATE TABLE `device_media_log` (
  `device_media_id` bigint(20) NOT NULL AUTO_INCREMENT,
  `device_id` int(11) NOT NULL DEFAULT '0',
  `media_id` bigint(20) NOT NULL DEFAULT '0',
  `playback_type_id` tinyint(4) NOT NULL DEFAULT '0',
  `playback_id` int(11) NOT NULL DEFAULT '0',
  `play_date` date DEFAULT NULL,
  `start_time` time DEFAULT NULL,
  `end_time` time DEFAULT NULL,
  `client_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`device_media_id`),
  KEY `Index_media_id` (`media_id`),
  KEY `Index_device_id` (`device_id`),
  KEY `Index_play_date` (`play_date`),
  KEY `Index_start_time` (`start_time`),
  KEY `Index_end_time` (`end_time`),
  KEY `Index_client_id` (`client_id`)
) 
ENGINE=InnoDB AUTO_INCREMENT=8366229 DEFAULT CHARSET=latin1

添加复合索引后描述 -+--------+--------------+----- +- --------+------+------+--------+ | 1 | 简单 | 设备媒体日志 | 索引 | 空 | index_composite | 12 | 空 | 10 | |

4

1 回答 1

1

试试这个查询

SELECT device_id
   ,media_id
   ,limit1.play_date
   ,limit1.start_time
   ,limit1.end_time
   ,SUBTIME(limit1.end_time, limit1.start_time) AS playback_duration
FROM 
   device_media_log
ORDER BY 
    play_date DESC
    ,start_time DESC
    ,end_time DESC 
limit 0, 10;

不需要子查询,因为您直接使用结果。解释语句还显示没有使用您创建的索引。

在以下列创建复合索引play_date, start_time, end_time

ALTER TABLE device_media_log ADD INDEX device_media_log_date_time(play_date, start_time, end_time);

希望这可以帮助...

于 2013-06-04T05:41:09.720 回答