1

我有下表,其中有 200 万行。

CREATE TABLE `gen_fmt_lookup` (
  `episode_id` varchar(30) DEFAULT NULL,
  `media_type` enum('Audio','Video') NOT NULL DEFAULT 'Video',
  `service_id` varchar(50) DEFAULT NULL,
  `genre_id` varchar(30) DEFAULT NULL,
  `format_id` varchar(30) DEFAULT NULL,
  `masterbrand_id` varchar(30) DEFAULT NULL,
  `signed` int(11) DEFAULT NULL,
  `actual_start` datetime DEFAULT NULL,
  `scheduled_start` datetime DEFAULT NULL,
  `scheduled_end` datetime DEFAULT NULL,
  `discoverable_end` datetime DEFAULT NULL,
  `created_at` datetime DEFAULT NULL,
  KEY `idx_discoverability_gn` (`media_type`,`service_id`,`genre_id`,`actual_start`,`scheduled_end`,`scheduled_start`,`episode_id`),
  KEY `idx_discoverability_fmt` (`media_type`,`service_id`,`format_id`,`actual_start`,`scheduled_end`,`scheduled_start`,`episode_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |

下面是我在这张表上运行的解释查询

mysql> EXPLAIN select   episode_id,scheduled_start 
from gen_fmt_lookup  
where media_type='video' 
and service_id in ('mobile_streaming_100','mobile_streaming_200','iplayer_streaming_h264_flv_vlo','mobile_streaming_500','iplayer_stb_uk_stream_aac_concrete','captions','iplayer_uk_stream_aac_rtmp_concrete','iplayer_streaming_n95_3g','iplayer_uk_download_oma_wifi','iplayer_uk_stream_aac_3gp_concrete') 
and genre_id in ('100001','100002','100003','100004','100005','100006','100007','100008','100009','100010') 
and NOW() BETWEEN actual_start and scheduled_end 
group by episode_id order by min(scheduled_start) limit 1 offset 100\G
*************************** 1. row ***************************
           id: 1
  select_type: SIMPLE
        table: nitro_episodes_gen_fmt_lookup
         type: range
possible_keys: idx_discoverability_gn,idx_discoverability_fmt
          key: idx_discoverability_gn
      key_len: 96
          ref: NULL
         rows: 31719
        Extra: Using where; Using index; Using temporary; Using filesort
1 row in set (0.16 sec)

所以我的问题是

  • 查询执行中使用的索引是否最好?如果没有,有人可以建议更好的索引吗?
  • mysql可以在where子句中使用带有2个日期的复合索引吗?与上面的查询一样,where 子句具有条件“and NOW() BETWEEN actual_start 和 schedule_end”,但 mysql 使用的索引 'idx_discoverability_gn' 的键长度仅为 96。这意味着它仅使用 index upto ( media_type, service_id, genre_id, actual_start) 。为什么不能使用 index upto ( media_type, service_id, genre_id, actual_start, scheduled_end) ?
  • 我还能做些什么来提高性能?
4

1 回答 1

0

您有范围检查,因此 (scheduled_start, actual_start, scheduled_end) 上的聚集索引可能会有所帮助。您当前的索引不是很有用。您可以摆脱它们并构建一个主键(episode_id)和另一个索引(service_id,genre-id,episode_id)

于 2012-07-31T18:00:26.670 回答