我正在使用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
答案 0 :(得分:2)
请注意,插入BTree索引的中间确实需要经常释放页面,并重建索引的一部分。对于聚簇索引(您的主键可能是您的聚簇索引),在重建页面时也必须移动实际的行数据。
如果行数据很大,则需要一些时间。
对于您的情况,最好使用自动增量主键,并且只在sessId上使用唯一索引,因此您不会将记录插入到聚簇索引的中间。
答案 1 :(得分:2)
在不是VM的东西上重现问题,然后你可以抱怨。
根据我的经验,虚拟机,特别是与任意第三方共享的虚拟机,具有无法依赖的行为。
很可能,innoDB正在尝试执行fdatasync()。这需要做一些实际的物理IO,它被主机盒上的另一个任务(可能是另一个VM)阻塞。如果你不控制它们,就无法预测它的行为。
如果会话表不需要在数据库关闭期间保持持久性,请考虑ENGINE = Memory。
如果您没有强大的数据持久性要求,那么减少innodb持久性设置(但这会影响整个服务器而不仅仅是表格)
答案 2 :(得分:0)
按照建议尝试使用代理自动增量键,但在执行查询时仍然存在速度问题。
解决方案是将表格的引擎切换到更快插入的MyISAM。