解释我没有编写的复杂查询的选择输出

时间:2014-06-26 08:21:44

标签: mysql sql database performance

我正在编写一个我没有编写的代码库,而且我们的SQL查询的性能非常糟糕,所以我认为我们可能会错过一些索引,但是很糟糕 - 书面查询等我们正在使用MySQL。我已经可以看到我们通过类型名称查询的方式,而不是某种类型的数据库,因为数据库是一团糟。我正在尝试做一个解释查询来弄清楚为什么这个查询在运行时方面是最大的攻击者。

EXPLAIN 
 SELECT COUNT(v.id) cnt
   FROM non_detail_video_views vv
   JOIN video v
     ON vv.video_id = v.id
   JOIN video_sub_category c
     ON v.video_sub_category_id = c.id
  WHERE DATE(FROM_UNIXTIME(vv.created_date)) = '2014-06-25'
    AND c.sub_category_name IN ('Rap','R&B','Country','Pop','Metal','Rock'
                               ,'EDM','Christian','Alternative','Jazz','Blues'
                               ,'Reggae','Classical','Folk','Trance') 
  GROUP 
     BY vv.video_id
  ORDER 
     BY vv.created_date DESC;

我问过直接访问数据库的人来运行查询,他给了我一个截图:

query

这是non_detail_video_views表:

CREATE TABLE IF NOT EXISTS `non_detail_video_views` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `video_id` int(11) NOT NULL,
  `sharer_id` int(11) NOT NULL,
  `member_id` int(11) NOT NULL,
  `is_newgame` int(11) NOT NULL,
  `frompage` int(11) NOT NULL,
  `from_country` varchar(255) NOT NULL,
  `ip_address` varchar(255) NOT NULL,
  `created_date` int(11) NOT NULL,
  `updated_date` int(11) NOT NULL,
  `active` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `id` (`id`),
  KEY `video_id` (`video_id`),
  KEY `created_date` (`created_date`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

视频表:

CREATE TABLE IF NOT EXISTS `video` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `referral_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `video_title` varchar(255) NOT NULL,
  `video_description` varchar(2048) DEFAULT NULL,
  `video_url` varchar(1024) NOT NULL,
  `video_html` varchar(2048) NOT NULL,
  `video_category_id` int(11) NOT NULL,
  `video_sub_category_id` int(11) NOT NULL,
  `video_thump` varchar(255) NOT NULL,
  `price` decimal(10,2) NOT NULL,
  `payment_type` int(11) NOT NULL,
  `in_contest` int(11) NOT NULL DEFAULT '0',
  `repeater` int(11) NOT NULL DEFAULT '1',
  `coupon_code` varchar(255) NOT NULL,
  `created_date` int(11) NOT NULL,
  `updated_date` int(11) NOT NULL,
  `active` int(11) NOT NULL,
  `noofshares` varchar(255) NOT NULL,
  `besides` int(11) NOT NULL,
  `facebookpage` varchar(255) NOT NULL,
  `custom_message` varchar(255) NOT NULL,
  `custom_link` varchar(255) NOT NULL,
  `video_country_id` varchar(255) NOT NULL,
  `ages` varchar(255) NOT NULL,
  `gender` int(11) NOT NULL,
  `duration` int(11) NOT NULL,
  `likes` int(11) NOT NULL,
  `views` int(11) NOT NULL,
  `comments` varchar(255) NOT NULL,
  `subscribers` varchar(255) NOT NULL,
  `pay_per_view` double(10,2) NOT NULL,
  `total_payment` double(10,2) NOT NULL,
  `pending_amount` double(10,2) NOT NULL,
  `second_payment` int(11) NOT NULL,
  `welcome_mail` int(11) NOT NULL,
  `add_budget_mail` int(11) NOT NULL,
  `auto_mid_way` int(11) NOT NULL,
  `out_of_budget` int(11) NOT NULL,
  `out_of_budget_2` int(11) NOT NULL,
  `out_of_budget_3` int(11) NOT NULL,
  `is_refunded` int(11) NOT NULL,
  `refund_date` int(11) NOT NULL,
  `is_banned` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `id` (`id`),
  KEY `video_id` (`video_url`(767)),
  KEY `created_date` (`created_date`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

video_sub_category表:

CREATE TABLE IF NOT EXISTS `video_sub_category` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `category_id` int(11) NOT NULL,
  `sub_category_name` varchar(255) NOT NULL,
  `genre_id` int(11) NOT NULL,
  `created_date` int(11) NOT NULL,
  `updated_date` int(11) NOT NULL,
  `active` int(11) NOT NULL DEFAULT '1',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1;

我之前没有这样做,我该如何解释输出?

1 个答案:

答案 0 :(得分:1)

我唯一可以建议如下。而不是做所有的步骤,然后尝试你的查询,我建议你尝试第一步,然后查询,然后第二步,然后查询等。我知道不是很科学,但那是我如何滚动...

  1. 将日期比较更改为WHERE vv.created_date BETWEEN 1403650800 AND 1403737199

  2. 删除vv.video_id和vv.created_date上的现有索引,而是在这些列上创建复合索引。

  3. 在v.video_sub_category_id上添加索引

  4. 在c.sub_category_name上添加索引