我正在处理的脚本旨在更新数据库表,该数据库表记录了使用国家和所有IP地址(或几乎所有IP地址)的状态。目前我保持简单,只从5个RIR(地区互联网注册管理机构)获取数据并将其保存到我的数据库。
最初速度是不切实际的,但是通过减少日志中的信息量并将SQL插入分组为1000个组并使用单个查询,它们已经显着改进。但是,现在运行脚本时,SQL插入速度的变化非常大,我想知道是否有人知道原因。
以下是我录制的一些速度。在测试中,我分离了在PHP中执行脚本迭代所花费的时间以及应用sql语句所花费的时间,我没有在下面的列表中包含PHP时间,因为效果可以忽略不计;即使是最大的数据块,也不会超过1秒。
测试速度(插入的数据行数始终保持不变)
测试1 总SQL执行时间:33秒
测试2 总SQL执行时间:72秒
测试3 总SQL执行时间:78秒
其他测试持续在~30秒至约80秒之间波动。
我有两个问题:
1)我是否应该接受这些差异作为世界的方式,还是有理由让它们出现?
2)我感到紧张的是将~185000行插入集中到一个查询中。有什么理由我应该避免对这些插入使用一个查询吗?我之前没有使用过这么多数据。
谢谢
__
数据库表如下。
Sorage Engine - InnoDB
列:
id - int,主键
registry - varchar(7)
code - varchar(2)
type - varchar(4)
start - varchar(15)
value - int
日期 - 日期时间
status - varchar(10)
答案 0 :(得分:3)
1) Should I accept these disparities as the way of the world, or is there a reason for them?
速度的变化可能是由于使用磁盘IO的竞争进程 - 所以等待资源。如果这是一个生产服务器而不是一个孤独的测试服务器,那么当然其他一些进程正在请求访问该磁盘。
2) I felt nervous about lumping the ~185000 row inserts into one query. Is there any reason I should avoid using one query for these inserts? I've not worked with this amount of data being saved at one time before.
您还应该将插入分成X个插入组,并将每个组作为事务插入。
除了实验之外,以其他方式确定X的值很难。
将插入分组到事务中可确保仅在每个事务之后(而不是在每个(自动提交的)插入之后)将数据写入(提交)到磁盘。
这对磁盘IO有很好的影响,如果将多个插入分组到一个事务中,则会对可用内存产生不良影响。如果未提交的数据量对于当前内存而言太大,则DBMS将开始将数据写入内部日志(在磁盘上)。
因此X取决于插入的数量,与每个插入关联的数据量,允许的内存/用户/会话参数。还有很多其他的东西。
percona提供了一些很酷的(免费)工具。它们可以帮助您监控数据库活动
您还可以查看vmstat 看-n .5'vmstat'
查看生产环境活动写入磁盘的数据量和变化。
启动你的脚本,等到你发现写入磁盘的字节数增加了。如果编写步骤几乎是一个恒定的值(高于正常的生产用途)那么它就是颠簸&交换,如果它有节奏,那么它只是写作提交。