希望有人可以帮我解决这个问题。我需要列出下面ngr_titles
的所有200条记录,并加入ngr_monitordata
中最新的相关记录。 ngr_monitordata中的外键称为titleid
,最新值应为每个标题的较高when_posted
值。
问题是ngr_monitordata
包含数百万条记录并且每秒都在增加。
这是我使用的查询,但执行需要14秒:
SELECT * FROM ngr_titles
LEFT JOIN
(SELECT titleid, MAX(when_posted) FROM ngr_monitordata GROUP BY titleid) tmp1
ON ngr_titles.id= tmp1.titleid;
最好的方法是什么?
表格是:
CREATE TABLE `ngr_titles` (
`id` int(11) NOT NULL auto_increment,
`title` varchar(255) default NULL,
`drop_min` int(11) NOT NULL default '50',
`warn_pcnt` float(5,1) NOT NULL default '15.0',
`crit_pcnt` float(5,1) NOT NULL default '25.0',
`deviations` float(5,1) NOT NULL default '2.0',
`addlobby` int(2) NOT NULL default '0',
`url` varchar(255) default NULL,
`graph_url` varchar(255) default NULL,
`lastchecked` int(11) NOT NULL default '0',
`last_exception` int(11) default NULL,
`state` enum('ok','warning','critical') default NULL,
`trend` int(11) NOT NULL default '0',
`short_name` varchar(45) NOT NULL,
`historical` varchar(45) NOT NULL,
`cacti_url` varchar(255) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `title` (`title`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `ngr_monitordata` (
`id` int(11) NOT NULL auto_increment,
`titleid` int(11) default NULL,
`when_posted` int(11) default NULL,
`games_completed` int(11) default NULL,
`games_created` int(11) default NULL,
`games_in_progress` int(11) default NULL,
`games_in_progress_gps` int(11) default NULL,
`users_in_games` int(11) default NULL,
`users_in_games_gps` int(11) default NULL,
`users_in_lobby` int(11) default NULL,
`users_in_passive` int(11) default NULL,
`users_in_rooms` int(11) default NULL,
`rooms` int(11) default NULL,
`state` enum('ok','warning','critical','unknown') NOT NULL default 'ok',
`user_drop` int(11) NOT NULL default '0',
`retries` int(8) default NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `whowhenidx` (`titleid`,`when_posted`),
KEY `whenidx` (`when_posted`),
KEY `titleidx` (`titleid`),
KEY `stateidx` (`state`)
) ENGINE=MyISAM AUTO_INCREMENT=120512615 DEFAULT CHARSET=utf8;
答案 0 :(得分:1)
尽可能不要使用内部查询。它会很慢。
SELECT ngr_titles.*, MAX(ngr_monitordata.when_posted) as when_posted
FROM ngr_titles
LEFT JOIN ngr_monitordata
ON ngr_titles.id = ngr_monitordata.titleid
GROUP BY ngr_titles.id
编辑:仅当两个表的大小相同时才适用。
答案 1 :(得分:0)
SELECT
t.*
FROM
ngr_titles t
INNER JOIN
ngr_monitordata m
ON
t.id = m.titleid
AND
m.when_posted = (SELECT MAX(when_posted) FROM ngr_monitordata WHERE titleid = t.id)
快速解决方案,它应该可以工作,虽然我是在急速写的。如果是我,我会稍微规范化数据,以减少聚合函数和子查询的开销。
答案 2 :(得分:-1)
尝试为以下列ngr_monitordata
添加(titleid ASC, when_posted DESC)
的索引。