高磁盘IO,如何缓解?

Dis*_*sco 8 mysql innodb

我是程序员,不是 DBA。要温柔 :)

概述

  • InnoDB、MySQL
  • mod_perl 脚本,持久连接
  • 成千上万的用户每 20 秒调用一次脚本

问题

  • 高磁盘 IO(大概是由更新引起的[?])会减慢一切,造成巨大的瓶颈。

查询

  1. UPDATE [单表] SET refreshTime 到当前时间戳,在 WHERE 子句中有两个相同的表检查
  2. SELECT COUNT(*) [四表连接,带索引],以及 WHERE 子句中的一堆 AND(仍然很简单)
  3. SELECT a,b [四个表连接,相同的四个表],以及 WHERE 子句中的一堆 AND(也很简单)

查询缓存开启。

解决方案?

  • 我不是 DBA,但我怀疑 RAM 中可能有一个表,它会定期(每 10 秒?)更新到磁盘上,并且在发生灾难性故障时,会自动从磁盘表中填充 RAM 表重新启动后,但我不知道这是否真的可行,它是否是最佳解决方案或有哪些其他选择。
  • 有什么想法或建议吗?再说一次,我是一名程序员,所以如果有人认识这样做的人,或者可以向我指出非常具体的资源,我将不胜感激。

~~~~~~~

CREATE TABLE `openInvitations` (
`id` int(99) NOT NULL auto_increment,
`createTime` timestamp NULL default NULL,
`repAcceptTime` timestamp NULL default NULL,
`rep_id` varchar(64) NOT NULL default '',
`repRefreshTime` timestamp NULL default NULL,
`customer_macAddr` varchar(14) NOT NULL default '',
`customerRefreshTime` timestamp NULL default NULL,
`stage` char(1) NOT NULL default 'P',
`parent` varchar(25) default NULL,
`reason` varchar(64) default NULL,
PRIMARY KEY  (`rep_id`,`customer_macAddr`),
UNIQUE KEY `id` (`id`),
KEY `customer_macAddr` (`customer_macAddr`),
CONSTRAINT `openInvitations_ibfk_1` FOREIGN KEY (`rep_id`) REFERENCES `rep` (`id`),
CONSTRAINT `openInvitations_ibfk_2` FOREIGN KEY (`customer_macAddr`) REFERENCES `customer` (`macAddr`)
) ENGINE=InnoDB AUTO_INCREMENT=0 DEFAULT CHARSET=latin1
Run Code Online (Sandbox Code Playgroud)
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE oi ref PRIMARY,customer_macAddr customer_macAddr 16 const 1 使用 where; 使用索引
1 SIMPLE r eq_ref PRIMARY,FK_rep_1 PRIMARY 66 xxx.oi.rep_id 1 使用 where
1 SIMPLE s eq_ref PRIMARY,FK_subscriber_1 PRIMARY 27 xxx.r.subscriber_id 1 使用 where
1 简单 c eq_ref PRIMARY PRIMARY 4 xxx.s.charge_id 1 使用 where
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE oi ref PRIMARY,customer_macAddr customer_macAddr 16 const 1 使用 where
1 SIMPLE r eq_ref PRIMARY,FK_rep_1 PRIMARY 66 xxx.oi.rep_id 1 使用 where
1 SIMPLE s eq_ref PRIMARY,FK_subscriber_1 PRIMARY 27 xxx.r.subscriber_id 1 使用 where
1 简单 c eq_ref PRIMARY PRIMARY 4 xxx.s.charge_id 1 使用 where
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE openInvitations ALL customer_macAddr NULL NULL NULL 5258 使用 where

修复查询后:

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE openInvitations ref customer_macAddr customer_macAddr 16 const 1 使用 where

dab*_*st1 7

正如 DTest 所指出的,请提供有关您的问题的更多信息。

关于缓存,您可能会增加 innodb 缓冲池的大小,以允许在内存中缓存更多数据和索引。如果您经常更新,您可能无法从查询缓存中受益,最好将该 RAM 用于 innodb 缓冲池。

如果您想将所有数据和索引放在 RAM 中,那么 MySQL Cluster 可能是您的答案。

编辑
看起来您的 SELECT 语句正在使用正确的索引。你能为你的更新声明提供一个解释计划吗?您必须将其重写为 SELECT 语句才能执行此操作。做一个SELECT * FROM相同的表,并与同where子句作为您的UPDATE语句。

  • 通过乔治,我认为找到了。:) 我认为这是查询本身的一个错误,虽然它有效,但更新的行数比必要的多几千行。通宵运行,明早更新。谢谢! (3认同)
  • 好多了。问题是我的一个手术室里没有钥匙。这里的 DBA StackExchange 社区礼仪是什么?我是将这个答案标记为“正确”,还是回答我自己的问题并将其标记为正确? (3认同)

Dis*_*sco 5

该问题是由于我在 UPDATE 中的 OR 语句之一中未包含键。

感谢“dabest1”帮助我找到答案。