在我的办公室,我们有一个遗留的会计系统,它将所有数据存储在具有固定宽度记录的纯文本文件(TXT扩展名)中。每个数据文件都被命名为例如FILESALE.TXT。我的目标是将这些数据导入MySQL服务器,以供许多其他无法与传统软件连接的程序进行只读使用。每个文件基本上都是一个表。
我需要访问大约20个文件,大约1GB的总数据。每行可能是350-400个字符宽,有30-40列。拉入数据后,没有MySQL表比100mb大得多。
旧版会计系统可以修改文本文件中的任何行,删除旧行(它有一个已删除的记录标记 - 0x7F),并随时添加新行。
几年来,我每隔5分钟就开始一次cron工作:
TRUNCATE表并将新数据导入我们的MySQL服务器,如下所示:
START TRANSACTION;
TRUNCATE legacy_sales;
LOAD DATA INFILE '/tmp/filesale.data' INTO TABLE legacy_sales;
COMMIT;
cron脚本运行每个文件检查并行并行解析,因此整个更新过程实际上并不需要很长时间。最大的表(不经常更改)需要大约30秒才能更新,但大多数表只需不到5秒。
这一直运作正常,但有一些问题。我想它与数据库缓存混淆,所以每次我必须TRUNCATE和LOAD一个表,其他使用MySQL数据库的程序起初很慢。此外,当我切换到并行运行更新时,数据库可能会处于稍微不一致的状态几秒钟。
整个过程看起来非常低效!有没有更好的方法来解决这个问题?关于可能值得调查的优化或程序的任何想法?任何面临类似情况的人都有任何巧妙的伎俩吗?
谢谢!
答案 0 :(得分:2)
一些想法:
如果文本文件中的行具有修改时间戳,则可以更新脚本以跟踪其运行时间,然后仅处理自上次运行以来已修改的记录。
如果文本文件中的行有一个可以充当主键的字段,则可以为该行维护指纹缓存,并以该ID为键。使用此选项可以检测行何时更改,并跳过未更改的行。即,在读取文本文件的循环中,计算整行的SHA1(或其他)散列,然后将其与缓存中的散列进行比较。如果它们匹配,则行没有改变,所以跳过它。否则,更新/插入MySQL记录并将新哈希值存储在缓存中。缓存可以是GDBM文件,memcached服务器,MySQL表中的指纹字段等等。这将使未更改的行保持不变(因此仍然缓存)在MySQL上。
在交易中执行更新以避免不一致。
答案 1 :(得分:0)
有两件事情浮现在脑海中,我不会详细介绍,但可以随意提问:
将文件处理卸载到应用程序服务器然后只填充mySQL表的服务,您甚至可以通过检查重复记录来构建智能,而不是截断整个表。
将处理卸载到另一台mysql服务器并复制/传输。
答案 2 :(得分:0)
我同意亚历克斯的提示。如果可以,只更新已修改的字段和批量更新,并将事务和多个插入分组。交易的另一个好处是更快的更新
如果您担心停机时间而不是截断表格,请插入新表格。然后重命名。
为了提高性能,请确保您对字段进行了适当的索引。
查看数据库特定的性能提示,例如 mysql中的_ delayed_inserts可以提高性能 _缓存可以优化 _即使您没有唯一的行,您也可以(或可能不)能够md5行