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 by
和join
之类的子查询总是一个好主意。有时它们工作得很好,但它们也可能很慢或让你在记忆方面遇到麻烦等。以上是关于MySQL InnoDB 表返回 20% 的行然后停止的主要内容,如果未能解决你的问题,请参考以下文章