我有一个查询,大约需要20秒,我想了解是否有方法来优化它。表1:
CREATE TABLE IF NOT EXISTS `sessions` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `user_id` (`user_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=9845765 ;和表2:
CREATE TABLE IF NOT EXISTS `access` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`session_id` int(10) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `session_id ` (`session_id `)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=9467799 ;现在,我要做的是计算连接到一个用户的所有会话的所有访问,所以我的查询是:
SELECT COUNT(*)
FROM access
INNER JOIN sessions ON access.session_id=session.id
WHERE session.user_id='6';user_id 6大约需要20个seconds...and,存储了大约300万个会话。我能做些什么来优化这个查询吗?
发布于 2014-01-11 00:48:31
从会话表中更改以下行:
KEY `user_id` (`user_id`)要这样做:
KEY `user_id` (`user_id`, `id`)这将为您做的是允许您从索引完成查询,而无需返回原始表。实际上,您需要对user_id的会话表进行索引扫描,并针对每个项目返回到表,以查找连接到access表的id。通过在索引中包含id,您可以跳过返回到表。
可悲的是,这将使您在该表中的插入速度变慢,而且这似乎是一笔竞标交易,因为只有一个用户有300万会话。Sql Server和Oracle将通过以下方式解决此问题:允许您在索引中包含id列,而无需对其进行实际索引,从而在插入时节省一些工作,还允许您为索引指定较低的填充因子,从而减少在插入时重新构建或重新排序索引的需要,但MySql不支持这些操作。
https://stackoverflow.com/questions/21049803
复制相似问题