mysql - 复杂最大语句 MySQL

标签 mysql sql query-optimization

我有一个查询可以从 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 万行。

是否有对我的表进行任何调整或对我的查询有任何建议以提高效率?

谢谢

最佳答案

您当前的查询存在几个问题。首先,子查询中的 GROUP BY 子句没有多大意义。其次,您在外部查询中使用没有 ORDER BYLIMIT ,这也没有意义。我建议使用以下版本:

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 的最大值。

关于mysql - 复杂最大语句 MySQL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54683301/

相关文章:

scala - Spark 数与拍摄和长度

mysql - 如何迭代优化 MySQL 查询?

php - 使用 foreach 语句选择 $_POST 返回错误

sql - 如何在mysql中创建计算字段?

java - 我得到 java.sql.SQLException : The connection does not exist

Java (Netbeans) - 如何在 if 语句中编写 "access denied"代码,我尽了最大努力,但没有成功..?

mysql - 当每个条目都适合中等大小的字段时,使用 MySQL 长文本大小的字段有什么缺点?

PHP连接但无法选择数据库

mysql - 事件记录 has_many

MySQL View 优化与子查询