vas*_*voc 5 mysql performance query-performance
我有一个运行在 Ubuntu 机器上的 MySQL 数据库,它每分钟 (24x7) ping 250 个客户端。我的列名是:
ip_address varchar(16),
status varchar(7),
timestamp datetime
Run Code Online (Sandbox Code Playgroud)
运行它几个星期,它已经增长(10,581,421+ 行)。我运行查询以返回特定 IP 地址上的最新 800 个结果:
SELECT *
FROM (
SELECT Device_ip, Status, timestamp
FROM ping_results
where Device_ip = '192.168.1.1'
order by timestamp desc
LIMIT 800
) SUB ORDER BY timestamp asc;
Run Code Online (Sandbox Code Playgroud)
返回结果需要 10+ 秒。有什么我可以做的不同的事情来加快速度吗?
您可以像这样跳出该子查询:
SELECT Device_ip, Status, timestamp
FROM ping_results
WHERE Device_ip = '192.168.1.1'
AND timestamp > DATE_SUB(NOW(), INTERVAL 800 MINUTE )
ORDER BY timestamp ASC
Run Code Online (Sandbox Code Playgroud)
这应该稍微简化查询计划,并且您只执行一个 ORDER BY 而不是两个。
正如其他人也提到的,索引是提高性能的一个好主意,并且可能不仅仅是操作查询。
查看查询,我发现您需要按升序检索 800 个最近的 ping。
您应该能够使用以下索引改进查询
ALTER TABLE ping_results ADD INDEX DEV_TIME_IP_NDX (`Device_ip`,`timestamp`,`ip_address`);
Run Code Online (Sandbox Code Playgroud)
这将通过以下方式帮助您的查询
ORDER BY
减少到特定的向后索引扫描device_ip
试一试 !!!
如果 ping_results 表有一id
列,您可能可以使用 JOIN 重做查询
SELECT B.Device_ip, B.Status, B.timestamp FROM
(
SELECT id FROM
(
SELECT id,timestamp FROM ping_results
where Device_ip = '192.168.1.1'
order by timestamp desc LIMIT 800
) SUB ORDER BY timestamp
) A LEFT JOIN ping_results B USING (id);
Run Code Online (Sandbox Code Playgroud)
创建我建议的索引后,您应该针对此查询和原始查询运行解释计划。然后,选择最佳解释计划或运行最快的查询。有可能,您的第一个查询应该足够了,因为它在查询优化器中需要处理的“噪音更少”。
顺便说一句,我使用 LEFT JOIN 因为 id 值将保持在子查询中的顺序。执行 INNER JOIN 会无意中对键进行重新排序。
归档时间: |
|
查看次数: |
716 次 |
最近记录: |