MySQL InnoDB 表返回 20% 的行然后停止

Posted

技术标签:

【中文标题】MySQL InnoDB 表返回 20% 的行然后停止【英文标题】:MySQL InnoDB table returns 20% of rows then halts 【发布时间】:2011-06-08 14:47:10 【问题描述】:

我正在尝试从电子邮件订阅的 mysql 数据库表中返回结果集。

该表名为 subscribe,如下所示:

    +-----------------+------------------+------+-----+---------------------+-------+
    | Field           | Type             | Null | Key | Default             | Extra |
    +-----------------+------------------+------+-----+---------------------+-------+
    | eid             | int(11) unsigned | NO   | PRI | NULL                |       |
    | subscribeStatus | varchar(4)       | NO   | PRI | NULL                |       |
    | transDate       | datetime         | NO   | PRI | 0000-00-00 00:00:00 |       |
    | senttoevDate    | datetime         | YES  |     | NULL                |       |
    +-----------------+------------------+------+-----+---------------------+-------+

PK 是 (eid,subscribeStatus,transDate) 并且有以下额外索引:

idxEid 开斋节, idxTDate 在 transDate

该表是一个 InnoDB 表。它包含大约 480K 行。

MySQL 的版本是 5.1.39 x86_64,我运行的是 Windows 7 64bit。

每次用户订阅或取消订阅电子邮件时,该表都会插入一行。我想知道所有用户的最新订阅状态。我要运行的查询是:

select 
  eid, transDate from subscribe s
where
  transDate = (select max(transDate) from subscribe si where si.eid = s.eid)

当我在 MySQL 查询浏览器(以及 TOAD for MySQL)中运行它时,它会立即返回大约 98K 行(到结果网格中),然后就挂起。我可以从 MySQL Administrator GUI 中看到状态是“正在发送数据”。我已经离开它长达一个小时,它还没有完成返回结果,甚至从 98K 开始。

我已调整 InnoDB 的 my.ini 参数以将 innodb_buffer_pool_size 增加到 3Gb(我的机器有 4Gb),但我可以从任务管理器中看到 mysqld 使用的内存从未超过 400K Mb。

我创建了一个 MyISAM 版本的表,看看是否更好,但它也挂起大约相同数量的返回行。

谁能提出为什么查询返回一些行但随后“挂起”,以及我可以做些什么来解决这个问题并让查询按应有的方式返回?

非常感谢您提供的任何帮助!

【问题讨论】:

@hristo 的查询更好,但我怀疑这更多是客户端(MySQL 查询浏览器)的问题,而不是实际的 mysql-server.... 【参考方案1】:

我不知道它为什么会挂起,但你为什么不试着用类似的东西来避免子查询

select eid, max(transDate) from subscribe group by eid

【讨论】:

非常感谢您的回复。我粘贴的选择缺少我感兴趣的关键字段,即 subscribeStatus。 抱歉,输入太快了!我错过了原始选择中的 subscribeStatus,这就是我感兴趣的值。我认为不使用子选择我无法获得它,但看起来我可以。 是的,效果很好。谢谢你。我想在考虑服务器参数和存储引擎之前,我只需要退后一步,看看表达我的查询的不同方式,并记住不同 RDBMS 之间的语法不同。 不错!一般来说,尽量避免在 mysql 中使用诸如group byjoin 之类的子查询总是一个好主意。有时它们工作得很好,但它们也可能很慢或让你在记忆方面遇到麻烦等。

以上是关于MySQL InnoDB 表返回 20% 的行然后停止的主要内容,如果未能解决你的问题,请参考以下文章

mysql中InnoDB存储引擎的行锁和表锁

MySQL InnoDB - 在使用连接表进行锁定读取期间,即使没有选择任何列,连接的行也会被锁定吗?

mysql 库表引擎

mysql 库表引擎

MYSQL的存储过程如何返回查询到的行数据?

Innodb引擎中Count(*)