MySQL查询效率不高(PHP搜索)

时间:2014-09-03 14:11:30

标签: mysql performance select

我想向用户显示他按国家/地区前缀拨打的电话数量。

我需要按国家/地区组合结果(因为每个国家/地区代码都有许多城市/地区的子代码)

我当前的查询需要80秒才能完成, 最重要的是,查询再次运行以进行分页, 以及总呼叫/时间的另一个查询。

这是一个非常繁重的DB(1gb +),每次搜索都需要几分钟才能完成,我想知道我是否可以让它更合理。

这是SQLfiddle

查询:

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'匹配。 同样,这是一个非常大的数据库,有更好的方法来执行此查询吗?

1 个答案:

答案 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