我遇到了一些性能问题,我认为可以通过更好的查询来解决。
MySQL表现在有33,000个条目,具有以下方案: ID - kompID(外键) - 时间(时间戳) - amountIO - amountNIO - status0 - .... - status8
每隔几秒钟就会插入一个类似上面的新报告,并在超过5天时删除它们。
出于监控目的,我需要为每个kompID提供最新的条目。这是因为我在Stackoverflow上找到了一个加入的想法:
SELECT
r1.kompID As ID,
(SELECT Name
FROM Komponenten
WHERE Komponenten.KompID = ID)
AS Name,
r1.time,
r1.status0,
...
FROM Reports r1
LEFT JOIN Reports r2
ON (r1.kompID = r2.kompID AND r1.RepID < r2.RepID)
WHERE r2.RepID IS NULL;
它可以工作,但是对于完整的数据库,查询需要150秒(在1 vCore上)。我可以增加内核,但我想了解可以做得更好的内容。
输出如下:
ID Name time status0 ....
1 470-U1 2015-08-24 14:00:30 2 ...
2 420-C 2015-08-24 14:00:33 0 ...
如果没有任何更快的查询,我也可以先选择所有的ComponentID,然后为每个选择最新的条目激发一个新的查询。
提前感谢您的帮助。
编辑: SQL结构
-- phpMyAdmin SQL Dump
-- version 4.0.10deb1
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Erstellungszeit: 24. Aug 2015 um 16:19
-- Server Version: 5.5.44-0ubuntu0.14.04.1
-- PHP-Version: 5.5.9-1ubuntu4.11
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
--
-- Datenbank: `AMS`
--
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `Reports`
--
CREATE TABLE IF NOT EXISTS `Reports` (
`RepID` int(11) NOT NULL AUTO_INCREMENT,
`kompID` int(11) NOT NULL,
`time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`AnzahlIO` int(11) NOT NULL DEFAULT '0',
`AnzahlNIO` int(11) NOT NULL DEFAULT '0',
`status0` int(11) NOT NULL,
`status1` int(11) NOT NULL DEFAULT '0',
`status2` int(11) NOT NULL DEFAULT '0',
`status3` int(11) NOT NULL DEFAULT '0',
`status4` int(11) NOT NULL DEFAULT '0',
`status5` int(11) DEFAULT '0',
`status6` int(11) NOT NULL DEFAULT '0',
`status7` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`RepID`),
KEY `FK_KomponentID` (`kompID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=53447 ;
--
-- Constraints der exportierten Tabellen
--
--
-- Constraints der Tabelle `Reports`
--
ALTER TABLE `Reports`
ADD CONSTRAINT `FK_KomponentID` FOREIGN KEY (`kompID`) REFERENCES `Komponenten` (`KompID`);
DELIMITER $$
--
-- Ereignisse
--
CREATE DEFINER=`root`@`%` EVENT `AutoDeleteOldReports` ON SCHEDULE EVERY 1 DAY STARTS '2015-08-10 10:46:57' ON COMPLETION PRESERVE ENABLE COMMENT 'Reports > 5Tage löschen' DO DELETE LOW_PRIORITY FROM AMS.Reports WHERE time < DATE_SUB(NOW(), INTERVAL 5 DAY)$$
DELIMITER ;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
小提琴链接在这里: http://sqlfiddle.com/#!9/9ed73(我希望它能像那样工作)
解释声明:
id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY r1 ALL NULL NULL NULL NULL 34560
1 PRIMARY r2 ref PRIMARY,FK_KomponentID FK_KomponentID 4 AMS.r1.kompID 16969 Using where; Using index; Not exists
2 DEPENDENT SUBQUERY Komponenten eq_ref PRIMARY PRIMARY 4 func 1
答案 0 :(得分:1)
好的,我刚刚注意到解决方案非常简单:
SELECT
(SELECT Name AS Name FROM Komponenten k1 WHERE k1.KompID = r0.kompID),
time,
AnzahlIO,
AnzahlNIO,
status0
FROM
(SELECT * FROM Reports ORDER BY RepID DESC) r0
GROUP BY kompID
因此,只需选择反向repID(带自动增量的主键),然后选择此项并按kompID分组。 像这样我们有0.001秒的运行时间。
非常感谢您的投入!
答案 1 :(得分:0)
使用此查询,您可以获得每个kompID的最新条目:
select * from Reports r0 where r0.kompID in (
select r1.kompID from (
select r1.kompID, max(time)
from Reports r1
group by r1.kompID ) );
“查询核心”显然如下:
select r1.kompID, max(time)
from Reports r1
group by r1.kompID
简单地按kompID分组,并为每个不同的kompID显示最大日期的那个。
希望我帮助过你!