我有这样的查询 -
SELECT c.msisdn,SUM(c.dataVolumeDownLink+c.dataVolumeUpLink) AS datasum
FROM cdr c
WHERE c.eveDate>='2013-10-29'
GROUP BY c.msisdn
ORDER BY datasum DESC;
这一节花了4分钟。我有一个关于evedate的索引。
CDR表包含从“2013-10-01”到“2013-10-30”每天的2400000条记录。但我想只选择前100条记录。我如何优化此查询。
我使用了限制条款,但它没有任何好处。
所以,请告诉我如何优化此查询。
谢谢。
答案 0 :(得分:1)
你刚才提出
LIMIT 100
之后.... ORDER BY datasum DESC here ;
like .... ORDER BY datasum DESC LIMIT 100;
答案 1 :(得分:1)
如果记录均匀分布,一天将有80k行。超过80k的GROUP BY
操作可能不需要4分钟(我猜)
我不确定你有以下索引:
INDEX(eveDate, msisdn)
使用上面的索引,记录按eveDate和msisdn排序,因此优化了GROUP BY
操作。即,相同的msisdns位于同一块。我想以下查询比你的查询更快。
<强> Q1 强>
SELECT x.msisdn, SUM(datasum)
FROM
(
SELECT c.msisdn AS msisdn,
SUM(c.dataVolumeDownLink+c.dataVolumeUpLink) AS datasum
FROM cdr c
WHERE c.eveDate>='2013-10-29'
GROUP BY eveDate, c.msisdn
) x
GROUP BY x.msisdn
ORDER BY SUM(datasum)
LIMIT 100;
或类似的东西。
<强> Q2 强>
SELECT c.msisdn SUM(c.dataVolumeDownLink+c.dataVolumeUpLink) AS datasum
FROM cdr c
WHERE c.eveDate>='2013-10-29'
GROUP BY c.msisdn
ORDER BY 100;
上面的查询更简单,但同样的msisdn可以位于另一个eveDate中。所以INDEX(eveDate, msisdn)
的好处有点儿。如果磁盘具有较大的可用空间,则在INDEX之后仅执行INDEX扫描。不需要数据。所有要求都在INDEX
INDEX(eveDate, msisdn, dataVolumeDownLink, dataVolumeUpLink)
嗯,如果仅附加数据,则永远不会更改附加数据。我想知道是否每天都做汇总表。
CREATE TABLE summary(eveDate, msisdn, datasum, INDEX(eveDate, msisdn);
每晚通过cronjob运行以下查询
INSERT INTO summary
SELECT NOW() c.msisdn,SUM(c.dataVolumeDownLink+c.dataVolumeUpLink) AS datasum
FROM cdr c
WHERE c.eveDate = NOW()
GROUP BY c.msisdn
然后你的查询会非常简单。
SELECT msisdn, SUM(datasum) as datasum
FROM summary
WHERE eveDate BETWEEN ? AND ?
答案 2 :(得分:0)
SELECT c.msisdn,SUM(c.dataVolumeDownLink+c.dataVolumeUpLink) AS datasum
FROM cdr c
WHERE c.eveDate>='2013-10-29'
GROUP BY c.msisdn
ORDER BY datasum DESC
LIMIT 0, 100;
答案 3 :(得分:0)
SELECT c.msisdn,SUM(c.dataVolumeDownLink+c.dataVolumeUpLink) AS datasum
FROM
(select * from cdr where eveDate>='2013-10-29' limit 100) as c
GROUP BY c.msisdn
ORDER BY datasum DESC;
拉里回答的微小变化
不完全确定我是否正确理解了这个问题
这将首先获取前100条记录并对其进行计算。
因此,最终结果可能少于100行,基于group by子句
编辑:
根据您的说明,您需要在c.msisdn上添加一个索引并在末尾添加一个限制子句
删除order by子句并放置一个外部查询,以便按< / p>
SELECT a.* FROM (
SELECT c.msisdn,SUM(c.dataVolumeDownLink+c.dataVolumeUpLink) AS datasum
FROM cdr c
WHERE c.eveDate>='2013-10-29'
GROUP BY c.msisdn limit 100) a
ORDER BY a.datasum DESC;
在c.msisdn
上添加索引