我想向用户显示他按国家/地区前缀拨打的电话数量。
我需要按国家/地区组合结果(因为每个国家/地区代码都有许多城市/地区的子代码)
我当前的查询需要80秒才能完成, 最重要的是,查询再次运行以进行分页, 以及总呼叫/时间的另一个查询。
这是一个非常繁重的DB(1gb +),每次搜索都需要几分钟才能完成,我想知道我是否可以让它更合理。
查询:
SELECT
sec_to_time(avg(t1.sessiontime)) as aloc,
CONCAT(TRUNCATE(sum(t1.terminatecauseid = 1) * 100 / count(*),1),'%') as asr,
count(t1.terminatecauseid = 1) as calls,
cast(t4.countryprefix as unsigned) as prefix,
t4.countryname as destination,
SEC_TO_TIME(sum(t1.sessiontime)) as duration
FROM
cc_call AS t1
inner join
cc_prefix as t2 ON t1.destination = t2.prefix
inner join
cc_country as t4 ON t1.destination like CONCAT(t4.countryprefix, '%')
WHERE
t1.card_id = '97' AND t1.starttime >= ('2013-04-1')
group by t4.countryprefix
order by duration DESC
LIMIT 0 , 100
这里的想法是迭代所有cc_country前缀,并使用LIKE查看它们是否与cc_call中的'destination'匹配。 同样,这是一个非常大的数据库,有更好的方法来执行此查询吗?
答案 0 :(得分:1)
所以摆脱like
的一个解决方案是:
SELECT
avg(t1.sessiontime) as aloc,
CONCAT(TRUNCATE(sum(t1.terminatecauseid = 1) * 100 / count(*),1),'%') as asr,
count(t1.terminatecauseid = 1) as calls,
t4.countryprefix as prefix,
t4.countryname as destination,
sum(t1.sessiontime) as duration
FROM
cc_call AS t1
inner join
cc_country as t4 ON left(t1.destination,length(t4.countryprefix)) = t4.countryprefix
WHERE
t1.card_id = '97' AND t1.starttime >= ('2013-04-1')
GROUP by t4.countryprefix
ORDER by duration DESC
LIMIT 0 , 100
我还在destination和countryprefix上添加了一个索引,可能会加快连接速度。
如果我所做的更改确实对您的查询产生了影响,那么您必须尝试使用这些数据。
此外,您获得了SQLFiddle here。
有关查询优化的一些有用信息here。