我只有一个查询,可从MySQL数据库获取 10个最大值。它返回了正确的值,但是问题是,获取该值花了很长时间
此值是来自设备的CPU数据。因此,从单个设备中获取大约 6个模块类型。每个模块类型都有大约 120个模块编号。每个模块号都有 2个插槽(活动和备用)。模块号放置在子架中。我需要获取具有最高价值的 10个模块编号。
我尝试使用自己的查询,它返回了正确的值,但是插槽不正确。然后我从堆栈溢出(MySQL query, MAX() + GROUP BY)中找到了一个查询
这是我的表格结构:
Create Table: CREATE TABLE `Router_Modul_CPU` (
`date_id` date NOT NULL,
`hour_id` time NOT NULL,
`NE` varchar(50) NOT NULL,
`modul_number` int(11) NOT NULL,
`modul_type` varchar(50) NOT NULL,
`slot` int(11) NOT NULL,
`subrack` int(11) DEFAULT NULL,
`mean_memory` float DEFAULT NULL,
`peak_memory` float DEFAULT NULL,
PRIMARY KEY (`date_id`,`hour_id`,`NE`,`modul_number`,`modul_type`,`slot`),
KEY `index_key` (`date_id`,`hour_id`,`NE`,`modul_number`,`modul_type`,`slot`,`subrack`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
这是我的查询:
select
Router_Modul_CPU.NE,
Router_Modul_CPU.modul_number,
Router_Modul_CPU.slot,
Router_Modul_CPU.subrack
from Router_Modul_CPU
inner join
(
select modul_number, max(peak_memory) as maks
from `Router_Modul_CPU`
group by modul_number, NE, subrack
) maxt on
(Router_Modul_CPU.modul_number = maxt.modul_number and
Router_Modul_CPU.peak_memory = maxt.maks)
where modul_type='SPU' and NE='R-D5-SBT' and date_id='2019-02-14'
limit 10
获取数据大约需要 40-50秒,而这些查询仅查询一台设备
所有这些数据每5分钟插入一次此表。现在此表有大约2500万行。
我的表是否需要调优,或者有什么建议可以提高查询效率?
谢谢
答案 0 :(得分:3)
您当前的查询存在几个问题。首先,子查询中的GROUP BY
子句没有多大意义。其次,在外部查询中使用LIMIT
而不使用ORDER BY
,这也是没有意义的。我建议使用以下版本:
SELECT
r1.NE,
r1.modul_number,
r1.slot,
r1.subrack
FROM Router_Modul_CPU r1
INNER JOIN
(
SELECT modul_number, MAX(peak_memory) AS maks
FROM Router_Modul_CPU
GROUP BY modul_number
) r2
ON r1.modul_number = r2.modul_number AND
r1.peak_memory = r2.maks
WHERE
r1.modul_type = 'SPU' AND
r1.NE = 'R-D5-SBT' AND
r1.date_id = '2019-02-14'
我已经省略了LIMIT
子句,如果您想使用一个子句,那么还必须提供一个ORDER BY
子句。
关于如何使其更好地执行,一种方法是将以下索引添加到Router_Model_CPU
表中:
CREATE INDEX your_idx ON Router_Model_CPU (modul_number, peak_memory);
有了这个索引,MySQL可能会选择加入它而不是当前的子查询。该索引应该可以使用,因为子查询只要求每个组peak_memory
的最大值。