2010-06-05 131 views
2

我正在使用MySQL来管理我的PHP应用程序的会话数据。测试应用程序时,通常非常快速且响应迅速。然而,看似随机的响应会在几秒钟后最终完成之前停顿。我已经缩小的问题倒在会话写入查询看起来是这样的:MySQL随机插入查询需要很长时间

INSERT INTO Session VALUES('lvg0p9peb1vd55tue9nvh460a7', '1275704013', '') ON DUPLICATE KEY UPDATE sessAccess='1275704013',sessData=''; 

慢速查询日志中有这样的信息:

Query_time: 0.524446 Lock_time: 0.000046 Rows_sent: 0 Rows_examined: 0 

出现这种情况大约每10次。查询通常只需要〜0.0044秒。

该表是InnoDB约60行。 sessId是带BTREE索引的主键。

由于这是在每个页面视图上访问的,显然这不是一个可接受的执行时间。这是为什么发生?

更新:表模式是:sessId:VARCHAR(32),sessAccess:INT(10),sessData:文本

+0

什么类型的列是sessData?请为您的表提供整个模式。 – 2010-06-05 03:01:37

+0

描述你的测试环境(处理器,RAM,磁盘,磁盘上的可用空间,还有哪些可能会与CPU/RAM /磁盘竞争的盒子上运行)。有时随机性能问题是环境问题。 – 2010-06-05 03:27:36

+0

该应用程序是在一个VPS主机计划与约300 MB的RAM。它是一个通常运行最小的网络软件的CentOS服务器。 – CrossProduct 2010-06-05 05:24:10

回答

2

需要注意的是插入到B树索引中确实需要的页面的释放相当频繁,并且重建了部分指数。对于聚集索引(您的主键可能是您的聚集索引),实际的行数据也必须在重建页面时移动。

如果行数据很大,则需要一些时间。

对于您的情况,最好使用自动增量主键,并且只对sessId使用唯一索引,所以您不会将记录插入到聚集索引的中间。

0

尝试使用代理自动增量键建议,但执行查询时速度仍然存在问题。

解决方案是将表格的引擎切换到MyISAM,它可以快速插入。

+0

MYISAM表怎么会插入比INNODB表更快? MyISAM引擎最适合阅读,而不适合写作。 – 2013-08-27 15:55:08

2

在不是虚拟机的东西上重现问题,然后您可以投诉。

根据我的经验,虚拟机器,特别是与任意第三方共享的虚拟机器具有无法依赖的行为。

很可能,innoDB正试图做一个fdatasync()。这需要执行一些实际的物理IO,这会被主机盒(可能是另一个VM)上的另一个任务阻止。如果你不控制它们,你无法预测它的行为。

如果会话表不需要在数据库关闭时保留,请考虑ENGINE = Memory。

如果你没有强大的数据持久性需求,进而降低InnoDB的耐久性设置(但是这会影响到整个服务器而不只是表)

+0

我看到您关于可能的虚拟机争用的观点。即使资源得到保证,每台机器上只有一个硬盘驱动器磁头。 我确实考虑过使用MEMORY引擎,但根据MySQL文档; “MEMORY表使用固定长度的行存储格式。”因此,这可能不是存储大小不同的二进制数据的最佳方式,特别是如果大多数条目都是空的。 – CrossProduct 2010-06-06 00:46:18

+0

您是否尝试在非VM上重现问题?如果可以的话,那么需要做更多的调查。一般来说,性能,延迟等在虚拟机上不如真正的硬件那么好,并且更不易预测。 – MarkR 2010-06-06 21:54:55