2013-03-05 28 views
0

在我的辦公室,我們有一個傳統會計系統,它將所有數據以純文本文件(TXT擴展名)存儲在固定寬度的記錄中。每個數據文件都被命名爲例如FILESALE.TXT。我的目標是將這些數據帶入我們的MySQL服務器,以供許多其他無法與傳統軟件進行交互的程序進行只讀使用。每個文件基本上都是一個表格。將傳統文本數據庫轉換爲SQL

總共有大約20個文件需要訪問,大約1GB的總數據。每行可能有350-400個字符,並且有30-40列。在拉入數據之後,沒有任何MySQL表大於100MB。

傳統會計系統可以修改文本文件中的任何行,刪除舊行(它具有已刪除的記錄標記 - 0x7F),並隨時添加新行。

這幾年裏,我一直在運行的cron作業每5分鐘即:

  1. 檢查的最後修改時間每個數據文件。
  2. 如果文件未被修改,請跳過它。否則:
  3. 解析數據文件,清理所有問題(只是非常簡單的檢查),並吐出我需要的列(我忽略的某些列)的製表符分隔文件。
  4. 截斷表,並導入新的數據到我們的MySQL服務器這樣的:

    START TRANSACTION; 
    TRUNCATE legacy_sales; 
    LOAD DATA INFILE '/tmp/filesale.data' INTO TABLE legacy_sales; 
    COMMIT; 
    

這個cron腳本運行的每個文件檢查和並行分析,所以整個更新過程中並沒有真正的需要很長時間。最大的表(不經常更換)需要約30秒才能更新,但大多數表需要不到5秒。

這一直工作正常,但也有一些問題。我猜它與數據庫緩存混淆,所以每次我必須對錶進行TRUNCATE和LOAD時,其他使用MySQL數據庫的程序起初速度很慢。另外,當我切換到並行運行更新時,數據庫可能會處於稍微不一致的狀態幾秒鐘。

這整個過程似乎非常低效!有沒有更好的方法來解決這個問題?有關可能值得研究的優化或程序的任何想法?來自任何面臨類似情況的人的任何巧妙的技巧?

謝謝!

+0

我想補充的一件事是,TRUNCATE在交易中不起作用! – Raolin 2013-04-24 18:53:55

回答

0

兩件事情浮現在腦海中,我不會去考慮太多的細節,但隨時提問:

  1. 可卸載的文件處理到應用服務器,然後只填充服務mySQL表,你甚至可以通過檢查重複記錄來建立智能,而不是截斷整個表。

  2. 將處理卸載到另一臺mysql服務器並複製/傳輸。

2

夫婦的想法:

  • 如果在文本文件中的行有一個修改時間戳記,您可以更新腳本,以保持它運行時的曲目,然後只處理記錄中自上次運行以來已被修改。

  • 如果文本文件中的行有一個可以充當主鍵的字段,則可以爲每個行保留一個指紋緩存,並由該ID進行鍵控。使用它來檢測行更改的時間,並跳過未更改的行。即,在讀取文本文件的循環中,計算整行的SHA1(或其他)散列,然後將其與緩存中的散列進行比較。如果它們匹配,那麼該行沒有改變,所以請跳過它。否則,更新/插入MySQL記錄並將新的哈希值存儲在緩存中。緩存可以是GDBM文件,memcached服務器,MySQL表中的指紋字段,無論如何。這將在MySQL上保留不變的行(因此仍然被緩存)。

  • 在事務內部執行更新以避免不一致。

0

我同意亞歷克斯的提示。如果可以,請僅更新已修改的字段,並使用事務和多個插入羣組進行批量更新。交易額外的好處是更快更新

如果您關心停機時間,而不是截斷表,插入到新表中。然後重命名它。

爲了提高性能,請確保您在字段上有適當的索引。

看看數據庫的特定性能的技巧,如 _在MySQL delayed_inserts提高性能 _高速緩存能夠優化 _即使你不具備的獨特行,你可能會(也可能不會)能夠MD5行

相關問題