繁体   English   中英

使用随机PRIMARY KEY列的值缓慢插入InnoDB表

[英]Slow INSERT into InnoDB table with random PRIMARY KEY column's value

对于我的网站,我使用Flickr的PHP API( http://www.flickr.com/services/api/ )。 此API提供了几种有用的方法来获取特定GPS位置周围的照片。

对API方法的调用看起来像URL,其中包含纬度,经度,API密钥,半径,排序等特定参数。比如,它看起来像http://api.flickr.com/method?lat=0.0&lon=0.0&radius=10

我的网站对API进行了超过200,000次调用,以生成包含Flickr图片的多个页面。 这是对API的极大推动,因此我在mySQL数据库中创建了一个结果缓存。

带缓存的InnoDB表的简化方案是:

char(32) request
datetime expires // 2-3 days
text     response // serialized data from API response

其中request是PRIMARY KEY,表示请求URI的MD5哈希。 其他领域很简单:)

当表变得足够大时,例如超过100,000行,就会出现问题。 INSERTs最多需要2秒(最多6(!)秒,1,000,000行)。

据我所知,问题在于PRIMARY INDEX和引擎是InnoDB。 每次插入新请求时,InnoDB引擎都会重建树索引并移动数据,因为MD5(请求)是一个非常随机的值。

那么......问题是是否有更好的方法来缓存这些请求? 或许我应该切换到MyISAM引擎? 或者可能是我应该尝试伪分区并创建几个表来解决问题? 或者可能只是使用BTREE而不是HASH索引?

欢迎任何想法!

编辑:

好吧,我试图改变桌子,因为Furicane和Johan建议,但仍然没有运气 - INSERT需要3秒钟。 当前request字段成为正常的非唯一索引,并且新的id列已添加为具有自动增量的PRIMARY KEY。 此外,我尝试在此表上添加4个分区,结果相同。

我认为request字段上的索引仍然是一个瓶颈。 我目前看到的唯一方法是确定所有可能的参数,将它们作为列添加到表中,然后在它们上创建索引。

还有其他想法吗? :)

编辑2:

Salman A在下面的评论中说他的相似表表现得更好(插入时约为0.03)。 这个问题可能出在系统上的IO负载上。 虽然我不能承受任何高负荷。

iostat结果:

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          22.94    0.71    8.42    8.50    0.00   59.43

Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
sda              38.01       151.04       114.32 1383655437 1047309046

iotop结果:

Total DISK READ: 152.91 K/s | Total DISK WRITE: 197.67 K/s

将mySQL放在列表的顶部,用于写入和阅读。 也许我的磁盘几乎死了? 如何检查磁盘性能?

InnoDB不支持hash键,只支持Btree。

MyISAM因不可靠而臭名昭着。
我认为您的问题是您使用MD5值作为主键。

主键包含在每个辅助密钥中。 PK被迫成为一把独特的钥匙。

设置整数自动增量主键并将MD5值设置为普通索引。
它甚至不需要是唯一的,因为这是减缓你速度的重要因素。

在此之后,您的插入应该运行得更快。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM