[英]Need help to optimize the My SQL query
我需要有关优化以下查询的帮助
select
DATE_FORMAT( traffic.stat_date, '%Y/%m'),
pt.promotion,
sum(traffic.voice_nat_onnet_mins - pt.promo_minutes_onnet) as total_onnet_mins,
sum(traffic.voice_nat_offnet_mins + traffic.voice_nat_landline_mins + traffic.voice_int_mins + traffic.voice_nng_mins + traffic.voice_not_rec_mins - pt.promo_minutes_offnet) as total_offnet_mins,
sum(traffic.sms_ptp_onnet_evts) as total_onnet_sms,
sum(traffic.sms_ptp_offnet_evts + traffic.sms_vas_pta_evts) as total_offnet_sms,
sum(traffic.dati_kb) as internet_kb
from
stats_novercanet.mnp_prod_stat_outgoing_traffic traffic
INNER JOIN stats_novercanet.mnp_prod_stat_promotion_traffic pt
ON pt.id_source_user=traffic.id_source_user
INNER JOIN stats_novercanet.mnp_prod_stat_customer_first_signup fs
ON pt.id_source_user = fs.id_source_user
where
traffic.stat_date between '2013-11-01' and '2013-11-30'
and traffic.stat_date >= (
select min(ft.stat_date)
from stats_novercanet.mnp_prod_stat_promotion_traffic ft
where
traffic.id_source_user=ft.id_source_user
and (ft.sub_rev>0 or ft.ren_rev>0)
and pt.promotion=ft.promotion
)
and pt.stat_date between '2013-11-01' and '2013-11-30'
group by
DATE_FORMAT( traffic.stat_date, '%Y/%m'),
pt.promotion
order by
DATE_FORMAT( traffic.stat_date, '%Y/%m'),
pt.promotion **
我已经为这个查询使用了explain,它向我显示了以下结果
+----+--------------------+---------+-------+------------------------------------------------+---------------------------------+---------+-----------------------------------------+--------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+--------------------+---------+-------+------------------------------------------------+---------------------------------+---------+-----------------------------------------+--------+----------------------------------------------+
| 1 | PRIMARY | pt | range | idx_prod_stat_pro_tra_stat_date,id_source_user | idx_prod_stat_pro_tra_stat_date | 4 | NULL | 530114 | Using where; Using temporary; Using filesort |
| 1 | PRIMARY | fs | ref | id_source_user | id_source_user | 5 | stats_novercanet.pt.id_source_user | 1 | Using where; Using index |
| 1 | PRIMARY | traffic | ref | stat_date,id_source_user | id_source_user | 5 | stats_novercanet.pt.id_source_user | 60 | Using where |
| 2 | DEPENDENT SUBQUERY | ft | ref | id_source_user,promotion | id_source_user | 5 | stats_novercanet.traffic.id_source_user | 93 | Using where |
+----+--------------------+---------+-------+------------------------------------------------+---------------------------------+---------+-----------------------------------------+--------+----------------------------------------------+
优化方面的任何帮助都将非常有用。 我已经在id_source_user,stat_date和Promotion上创建了索引,但是没有运气。 还尝试了联接中的子查询,但没有运气。
mnp_prod_stat_promotion_traffic的结果如下。 * *
| mnp_prod_stat_promotion_traffic | CREATE TABLE `mnp_prod_stat_promotion_traffic` (
`stat_date` date DEFAULT NULL,
`id_source_user` int(64) DEFAULT NULL,
`promotion` varchar(64) DEFAULT NULL,
`num_of_sub` int(64) DEFAULT NULL,
`num_of_ren` int(64) DEFAULT NULL,
`credit` float DEFAULT NULL,
`minutes` float DEFAULT NULL,
`kb` float DEFAULT NULL,
`sms` int(64) DEFAULT NULL,
`lbs` int(64) DEFAULT NULL,
`sub_rev` float DEFAULT NULL,
`ren_rev` float DEFAULT NULL,
`consumed_credit` float DEFAULT NULL,
`sim_type` varchar(32) DEFAULT NULL,
`price_plan` varchar(64) DEFAULT NULL,
`WiFi_mins` float DEFAULT NULL,
`over_min` float DEFAULT NULL,
`over_min_consumed` float DEFAULT NULL,
`over_sms` float DEFAULT NULL,
`over_sms_consumed` float DEFAULT NULL,
`over_data` float DEFAULT NULL,
`over_data_consumed` float DEFAULT NULL,
`promo_minutes_onnet` float DEFAULT NULL,
`promo_minutes_offnet` float DEFAULT NULL,
`promo_sms_onnet` int(64) DEFAULT NULL,
`promo_sms_offnet` int(64) DEFAULT NULL,
KEY `idx_prod_stat_pro_tra_stat_date` (`stat_date`),
KEY `id_source_user` (`id_source_user`),
KEY `promotion` (`promotion`) USING BTREE
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
您希望获得多少结果。 例如,如果您知道只希望返回一条记录,则可以使用LIMITS
运行查询时,它将在整个表中搜索该记录,但是如果您知道返回的只是一个,两个或三个结果,则可以进行LIMIT。 这将节省很多时间,但是MySQL再次取决于您要排除的结果数,因此您必须将其应用于运行它的表。
另外,另一个技巧是检查您使用的表类型。 请查看此网页以获取更多信息: http : //www.mysqltutorial.org/understand-mysql-table-types-innodb-myisam.aspx
另一个选择是构建脚本以使用上面的现有查询并将结果存储在新表中,并且每月仅在午夜时分通过cron运行脚本一次。 我这样做是为了进行分析,并且效果很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.