MySQL选择where需要很长时间

MySQL选择where需要很长时间,mysql,Mysql,我有一张大约700000行的桌子: CREATE TABLE IF NOT EXISTS `ext_log_entries` ( `id` int(11) NOT NULL AUTO_INCREMENT, `action` varchar(8) NOT NULL, `logged_at` datetime NOT NULL, `object_id` varchar(32) DEFAULT NULL, `object_class` varchar(255) NOT NULL,

我有一张大约700000行的桌子:

CREATE TABLE IF NOT EXISTS `ext_log_entries` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `action` varchar(8) NOT NULL,
  `logged_at` datetime NOT NULL,
  `object_id` varchar(32) DEFAULT NULL,
  `object_class` varchar(255) NOT NULL,
  `version` int(11) NOT NULL,
  `data` longtext COMMENT '(DC2Type:array)',
  `username` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `log_date_lookup_idx` (`logged_at`),
  KEY `log_user_lookup_idx` (`username`),
  KEY `log_class_lookup_idx` (`object_class`),
  KEY `log_version_lookup_idx` (`object_id`,`object_class`,`version`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1219777 ;
我尝试运行以下查询:

SELECT n0_.id AS id0, n0_.action AS action1, n0_.logged_at AS logged_at2, n0_.object_id AS object_id3, n0_.object_class AS object_class4, n0_.version AS version5, n0_.data AS data6, n0_.username AS username7 
FROM ext_log_entries n0_
WHERE n0_.object_id =275634
AND n0_.object_class = 'My\\MyBundle\\Entity\\Field'
AND n0_.version <=1
ORDER BY n0_.version ASC
我的查询只需要37秒就可以对结果中的1行执行。。。 我试图通过删除索引来运行相同的查询,但速度稍微快了一点:大约31秒

我不明白为什么我的查询要花这么多时间,为什么我的索引对性能没有帮助?你知道我如何才能在这个查询上有好的表现吗

提前感谢您的帮助

编辑

以下是索引的基数

log_date_lookup_idx         BTREE  logged_at        1221578 A       
log_user_lookup_idx         BTREE  username         40      A  YES  
log_class_lookup_idx        BTREE  object_class     1010    A       
log_version_lookup_idx      BTREE  object_id        1221578 A  YES  
                                    object_class    1221578 A   
                                    version         1221578 A

我找到了一个解决方案,不是解决方案,但至少它对我有效

我认为它可以帮助所有使用gedmo loggable的人,也可以帮助那些幸运地(像我一样)拥有只有整数ID的对象的人

我将列对象_id更改为整数,而不是varchar(255)。我的查询现在需要0.008秒!它对我有效,因为我确信我永远只有整数,对于那些有varchar的人,我很抱歉我尝试了很多东西,但没有任何效果

CREATE TABLE IF NOT EXISTS `ext_log_entries` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `action` varchar(8) NOT NULL,
  `logged_at` datetime NOT NULL,
  `object_id` int(11) DEFAULT NULL,
  `object_class` varchar(255) NOT NULL,
  `version` int(11) NOT NULL,
  `data` longtext COMMENT '(DC2Type:array)',
  `username` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `log_date_lookup_idx` (`logged_at`),
  KEY `log_user_lookup_idx` (`username`),
  KEY `log_class_lookup_idx` (`object_class`),
  KEY `log_version_lookup_idx` (`object_id`,`object_class`,`version`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1219777 ;

它运行缓慢的原因是它使用的是
log\u class\u lookup\u idx
索引,而不是
log\u version\u lookup\u idx
object\u id
列是否始终为数字?如果是这样,为什么它是varchar?
version
列和
object\u id
列的基数(唯一值的数量)是多少?还有,为什么要从…中选择1。。。您的结果集中不需要任何列值吗?我在测试中使用select 1,它没有任何意义。我的应用程序将选择表中的所有行。@Jon,我在原始邮件中添加了基数,谢谢您的回复!我将查询更改为与程序执行的查询同步,我希望我提供了所有需要的信息。我还在努力…这并不是在所有情况下都有效。假设一个实体的主键不是
autoincrement
。也就是说,主键是与另一个实体的关系,该实体具有返回字母数字值的
\uu toString
方法。在这种情况下,日志扩展将失败。也许,我只有自动增量ID。但是我不明白你的观点,_-toString方法会如何影响我们的案例,我们将ID存储在表中而不是_-toString方法结果否?我假设你使用的是条令。当你有一个像我上面解释的星座时(在大多数情况下,这是一对一的关系),那么条令本身就存储了
\u toString
值。也就是说,当一个实体与
用户
实体(我们对Symfony使用FOSUserBundle)相关时,我们可以观察到这种行为,该实体有一个内置的
\u toString
方法。因此,记录一对一相关实体中的更改会导致Doctrine存储用户名而不是
id
OK谢谢您的反馈,我想我很幸运没有将我的用户记录在我的loggable log_entries表中,所以我没有任何问题。
CREATE TABLE IF NOT EXISTS `ext_log_entries` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `action` varchar(8) NOT NULL,
  `logged_at` datetime NOT NULL,
  `object_id` int(11) DEFAULT NULL,
  `object_class` varchar(255) NOT NULL,
  `version` int(11) NOT NULL,
  `data` longtext COMMENT '(DC2Type:array)',
  `username` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `log_date_lookup_idx` (`logged_at`),
  KEY `log_user_lookup_idx` (`username`),
  KEY `log_class_lookup_idx` (`object_class`),
  KEY `log_version_lookup_idx` (`object_id`,`object_class`,`version`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1219777 ;