7

我正在编写的脚本旨在更新记录使用国家和所有 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 引擎 - InnoDB

列:

id - int,主键

注册表 - varchar(7)

代码 - varchar(2)

类型 - varchar(4)

开始 - varchar(15)

值 - 整数

日期 - 日期时间

状态 - varchar(10)

4

1 回答 1

2
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 watch -n .5 'vmstat'

查看生产环境的活动写入磁盘的数据量和变化。

启动您的脚本并等待,直到您注意到写入磁盘的字节数有所增加。如果写上一步几乎是一个恒定值(高于正常的生产使用),那么它就是颠簸和交换,如果它是有节奏的,那么它只是为提交而写。

于 2012-10-09T10:52:52.220 回答