sat*_*gie 6 mysql indexing myisam query-optimization freeradius
OS=centos 6.7 [Dedicated server]
memory=15G
cpu=Intel(R) Xeon(R) CPU E5-2403
mysql= V 5.1.73
Run Code Online (Sandbox Code Playgroud)
这是一个MyISAM表,包含大约500万行数据.在每5-6分钟插入大约3000个用户的数据(例如上传和下载速率,会话状态等).
表信息:描述"radacct"
从mysql慢查询日志中获取大部分时间的查询之一如下
Query_time: 7.941773 Lock_time: 0.155912 Rows_sent: 1 Rows_examined: 5377
use freeradius;
SET timestamp=1461582118;
SELECT sum(acctinputoctets) as upload,
sum(acctoutputoctets) as download
FROM radacct a
INNER JOIN (SELECT acctuniqueid, MIN( radacctid ) radacctid
FROM radacct
WHERE username='batman215'
and acctstarttime between '2016-02-03 12:10:47'
and '2016-04-25 16:46:01'
GROUP BY acctuniqueid) b
ON a.acctuniqueid = b.acctuniqueid
AND a.radacctid = b.radacctid;
Run Code Online (Sandbox Code Playgroud)
当有许多用户试图查看其消耗的带宽时,由于高负载和IO,服务器无法满足请求.我有什么办法可以进一步优化数据库吗?
表"radacct"的索引
谢谢
让我们从你的内部查询开始,这是:
SELECT acctuniqueid,
MIN( radacctid ) radacctid
FROM radacct
WHERE username='batman215'
and acctstarttime between '2016-02-03 12:10:47'
and '2016-04-25 16:46:01'
GROUP BY acctuniqueid
Run Code Online (Sandbox Code Playgroud)
您正在寻找相等匹配username和范围匹配acctstarttime.然后你acctuniqueid用来分组和拉出一个极值(MIN())radacctid.
因此,要加速此子查询,需要以下复合索引.
(username, acctstarttime, acctuniqueid, radacctid)
Run Code Online (Sandbox Code Playgroud)
这是如何运作的?将索引(这些是BTREE索引)视为其中值的排序列表.
username和BETWEEN范围的低端.BETWEEN范围的高端.这称为索引范围扫描.acctuniqueid,按顺序查找每个新值,然后取最低值 - 按顺序排列的第一个值 - radacctid然后向前跳到下一个值accuniqueid.这被称为松散的索引扫描,它奇迹般便宜.所以,添加复合索引.这可能会对您的查询性能产生重大影响.
您的外部查询看起来像这样.
SELECT sum(acctinputoctets) as upload,
sum(acctoutputoctets) as download
FROM radacct a
INNER JOIN ( /*an aggregate
* yielding acctuniqueid and raddactid
* naturally ordered on those two columns
*/
) b ON a.acctuniqueid = b.acctuniqueid
AND a.radacctid = b.radacctid
Run Code Online (Sandbox Code Playgroud)
为此,您需要复合覆盖指数
(acctuniqueid, radacctid, acctinputoctets, acctoutputoctets)
Run Code Online (Sandbox Code Playgroud)
这部分查询也满足于索引魔法.
(这就是所谓的覆盖,因为它包含了一些列中存在只是因为我们希望自己的价值,而不是因为我们希望他们编入索引.其他一些品牌和DBMS的模型允许包含在没有使他们搜索的索引额外列的索引.这是稍微便宜一点,特别是在INSERT操作方面.MySQL不这样做.)
因此,您的第一个操作项:添加这两个复合索引并重试您的查询.
从你的问题来看,你在桌面上放置了很多单列索引,希望它们可以加快速度.这是数据库设计中臭名昭着的反模式.尊重,您应该摆脱任何您不需要的索引.他们没有帮助查询,他们放慢速度INSERTS.那是你的第二个行动项目.
第三,请阅读 http://use-the-index-luke.com/这非常有帮助.
专业提示:你看到我如何格式化你的查询?ON当您必须了解查询时,开发清晰显示查询的表,列,条件和其他方面的个人格式约定非常重要.
| 归档时间: |
|
| 查看次数: |
1966 次 |
| 最近记录: |