2010-04-30 78 views
3

從德爾福2010到遠程MySQL 5.09服務器的插入速度極慢,這是一個主要的問題。從Delphi遠程插入到遠程MySQL數據庫的速度非常慢

到目前爲止,我曾嘗試:用

  • Zeoslib V7阿爾法
  • MyDAC
  • 我用配料和直接插入使用ADO(使用表MySQL的ODBC驅動程序

    • ADO訪問),並與Zeos我已經使用SQL插入與查詢,然後使用表直接模式,並使用applyupdates和提交緩存更新表模式。使用MyDAC我使用表訪問模式,然後直接SQL插入,然後批量SQL插入

      我試過的所有技術,我設置壓縮打開和關閉沒有可辨別的差異。

      到目前爲止,我已經看到了一個全面的相同7.5記錄每秒!

      現在,我想從這一點來看,假設遠程服務器速度很慢,但MySQL Workbench速度非常快,並且遷移工具包可以非常快速地管理初始遷移(說實話,我不記得有多快 - 哪種意味着它很快)

      編輯1

      速度會更快,我到SQL寫入文件,通過FTP上傳文件到服務器,然後將它導入直接在遠程服務器 - 我想知道他們是否會限制傳入的MySQL流量,但這並不能解釋爲什麼MySQL Workbench太快了!

      編輯2

      在最基本的層面上,代碼已經:

      while not qMSSQL.EOF do 
      begin 
          qMySQL.SQL.Clear; 
          qMySQL.SQL.Add('INSERT INTO tablename (fieldname1) VALUES (:fieldname1)'); 
          qMySQL.ParamByName('fieldname1').asString:=qMSSQL.FieldByName('fieldname1').asString; 
          qMySQL.ExecSQL; 
          qMSSQL.Next; 
      end; 
      

      我又試圖

      qMySQL.CachedUpdates:=true; 
      i:=0; 
      while not qMSSQL.EOF do 
      begin 
          qMySQL.SQL.Clear; 
          qMySQL.SQL.Add('INSERT INTO tablename (fieldname1) VALUES (:fieldname1)'); 
          qMySQL.ParamByName('fieldname1').asString:=qMSSQL.FieldByName('fieldname1').asString; 
          qMySQL.ExecSQL; 
          inc(i); 
          if i>100 then 
          begin 
          qMySQL.ApplyUpdates; 
          i:=0; 
          end; 
          qMSSQL.Next; 
      end; 
      qMySQL.ApplyUpdates; 
      

      現在,這個代碼與CachedUpdates:=False(這顯然從來沒有真正寫回到數據庫)速度快得要命!

      坦率地說,我認爲這是連接 - 我感覺這是連接...只是等待他們回到我身邊!

      感謝您的幫助!

    +0

    如果您顯示您的代碼,檢測您的瓶頸將非常有幫助 – 2010-04-30 15:46:10

    +1

    如果您使用本地服務器,插入速度有多快?也許這是一個與運輸有關的問題(連接速度慢)。 – mjn 2010-04-30 16:40:36

    +0

    您的代碼不正確。設置循環外部的SQL代碼*,然後調用Prepare。在循環內只分配參數並執行,否則會失去參數的優點。在循環之外明確地開始一個事務,並在最後提交。 CachedUpdates設置爲False意味着數據直接轉到數據庫,並且不會在本地緩存。不要使用CachedUpdates,它們不是爲了速度。 – 2010-05-04 12:15:31

    回答

    0

    你使用查詢參數嗎?插入的最快方法應該是使用普通查詢和參數(即INSERT INTO表(字段)VALUES(:field)),準備查詢,然後根據需要在單個事務中分配參數並執行多次 - 最後提交(不要使用任何味道的自動提交)

    在大多數數據庫中,每次執行查詢時都會避免硬解析,這需要時間。參數只允許查詢一次,然後根據需要重新執行多次。

    使用服務器設施來檢查發生了什麼 - 許多提供了一種方法來檢查正在運行的語句正在做什麼。

    +0

    我起初使用查詢參數和批量插入(我總是嘗試使用SQL第一,如果我可以)但平均速度是相同的:( – 2010-04-30 12:29:50

    +0

    我不會使用ADO批量插入,它可能會減少往返,但它獲得控制的插入,就像緩存更新一樣,恕我直言,方法是讓語句直接進入數據庫,儘可能減少開銷。無論如何,首先你必須找到瓶頸真正的位置。 – 2010-04-30 19:26:16

    +0

    正確答案Idsandon誰提到檢查服務器在這種情況下,可能會回答我的問題的設施(數據庫工作臺結果必須是虛假的) – 2010-05-03 08:08:12

    0

    我不知道ZeosLib,但使用ADO與ODBC驅動程序,您將無法獲得最快的方式插入的記錄,這裏沒幾步,可能使您的插入速度快:

    1. 使用Mydac對於直接訪問,它們不需要緩慢的ODBC> ADO> OLEDB> MySqlLib就可以連接到Mysql。

    2. 插入前首先打開連接。

    3. 如果您有大量插入,如1000或更多,請嘗試使用事務並在100條記錄或更多取決於記錄數後提交。

    即使使用ZeosLib或ADO,第3點可能會使您的插入速度更快。

    +0

    感謝您的回答,但是我已經嘗試過2&3(目前仍然安裝MyDAC) 我本來希望批量插入會更快,但它仍然以與插入一條記錄相同的平均速度出現在電線上的時間!? – 2010-04-30 12:28:53

    3

    你可以試試AnyDAC和它的Array DML功能。它可能會加速標準SQL INSERT幾次。

    +0

    感謝德米特里,我嘗試了一個演示,並且Array DML功能看起來非常有趣 - 但速度相當類似 – 2010-05-03 07:58:04

    +0

    我們嘗試使用MySQL數組dml - 這真的很快,看起來你的系統上有些東西會造成麻煩, – oodesigner 2010-09-23 05:25:23

    0

    你有兩件獨立的事情發生在這裏。首先,你的Delphi程序正在創建Insert語句並將它們發送到數據庫服務器,然後服務器正在處理它們。您需要檢查兩端以找到瓶頸。我不熟悉MySql工具,但我敢打賭,你可以很容易地找到一個SQL分析器。使用它來從Delphi應用程序中分析插入,並將其與Workbench工具中正在運行的插入進行比較,看看是否有顯着差異。

    如果不是,則放慢速度在您的應用程序中。嘗試將其連接到Sampling Profiler或其他一些瞭解Delphi的分析工具,它會告訴你在哪裏花費大量時間。一旦你知道了,那麼你可以努力攻擊這個問題,或者回到這裏問一個更具體的問題。但是,除非你知道問題來自哪裏,否則你在這裏得到的任何答案都只會被教育的猜測充其量。

    +0

    謝謝梅森,我是p retty確定它是服務器速度而不是我的代碼,我只是不是100%確定我正在使用mysql庫,和/或關於Delphi的最佳實踐是什麼,但它們似乎與我嘗試的類似無論如何。 – 2010-05-03 07:59:07

    1

    對不起,這個答覆很長時間後,你問這個問題。

    我有一個類似的問題。 BDS2006通過ODBC通過ODBC連接到MySQL - 花費25分鐘運行 - 每秒25個插入。我正在使用TDatabase連接並將TTable Tquery附加到它。準備好SQL語句。

    主要改進是當我開始在循環內開始交易。一個簡單的例子,Memebrships有會員期限。在插入成員和成員之前開始交易,之後再提交。成員數量爲01585,在交易之前花了279.90秒處理所有的會員記錄,但花了6.71秒。

    幾乎太好了,我們仍然在努力修復其他慢比特的代碼。

    也許馬克你已經解決了你的問題,但它可能會幫助別人。

    +0

    做了一些更改。 Commit是昂貴的,所以性能好的關鍵是選擇一個提交頻率,以平衡提交的開銷與持有事務的開銷太長。 – DavidG 2010-06-20 02:39:26

    +0

    經過進一步的調整後,我設法使用交易將運行時間從19分鐘減少到51秒。 – DavidG 2010-06-20 03:12:05

    +0

    +1非常感謝大衛!我實際上現在不記得我是否嘗試過交易,當你說在整個網絡中你是指通過本地網絡還是互聯網? – 2010-06-21 10:43:17