MySQL插入查询随机需要很长时间

时间:2010-06-05 02:49:35

标签: php mysql performance session innodb

我正在使用MySQL来管理我的PHP应用程序的会话数据。在测试应用程序时,它通常非常快速且响应迅速。然而,看似随机的响应将在几秒钟后最终完成之前停止。我把问题缩小到会话写入查询,看起来像这样:

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:text

3 个答案:

答案 0 :(得分:2)

请注意,插入BTree索引的中间确实需要经常释放页面,并重建索引的一部分。对于聚簇索引(您的主键可能是您的聚簇索引),在重建页面时也必须移动实际的行数据。

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

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

答案 1 :(得分:2)

在不是VM的东西上重现问题,然后你可以抱怨。

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

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

如果会话表不需要在数据库关闭期间保持持久性,请考虑ENGINE = Memory。

如果您没有强大的数据持久性要求,那么减少innodb持久性设置(但这会影响整个服务器而不仅仅是表格)

答案 2 :(得分:0)

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

解决方案是将表格的引擎切换到更快插入的MyISAM。