2013-04-07 38 views
0

我必須在MySQL中每次插入1000行數據。目前,我使用PDO和for-loop逐行插入數據庫。有沒有更有效的方法來實現更好的性能?因爲我必須將max_execution_time設置爲5分鐘。通過PDO插入1000行到MySQL的高效方法

function save() 
{ 
      return $query = $this->insert(" 
       INSERT INTO gadata (landing_page, page_title, page_views, visits, visitors, bounce_rate, pageviews_per_visit, time_on_page, avg_time_on_page, day, month, year, hour) 
       VALUES (:landing_page, :page_title, :page_views, :visits, :visitors, :bounce_rate, :pageviews_per_visit, :time_on_page, :avg_time_on_page, :day, :month, :year, :hour)", $this->data); 
} 

而且

protected function insert($sql, array $data) { 
    $q = $this->_db_handler->prepare($sql); 

    foreach ($data as $k => $v) 
    { 
     $q->bindValue(':' . $k, $v); 
    } 

    $q->execute(); 
} 
+0

確實的數據具有通過PHP應用要被插入?你可以上傳數據(即一個CSV文件),並使用mysql的本地'load data infile'? – 2013-04-07 12:54:13

+0

1000行很多是強制性的嗎? – user1370510 2013-04-07 12:54:56

+0

是的,我必須從其他Web服務獲取數據,並通過cronjob每天通過php代碼插入到MySQL中。 – hungneox 2013-04-07 12:56:19

回答

1

可能不是最好的解決辦法,但你可以嘗試構建一個查詢字符串像INSERT INTO [table] VALUES (r1c1,r1c2,r1c3),(r2c1,r2c2,r2c3) ...並執行一個mysql_query(或說爲幾百行的一個查詢),你甚至可能如果數據源不是來自信任源,則在構建sql查詢時以編程方式驗證數據。

+0

如果fast是關鍵,那麼像這樣的批量插入比單獨的語句更好。缺點是你必須自己逃避價值觀念,但肯定會更快。 – GolezTrol 2013-04-07 13:09:59

+0

爲什麼不爲這個查詢使用預準備語句?這很混亂,但顯然是可行的。 – 2013-04-07 13:29:55

1

參數化查詢根據定義交易執行安全性,減少數據項數量的靈活性。

你至少有2種可能性,以緩解:

  • 建立了SQL,然後在一次執行:

喜歡的東西:

$sql="INSERT INTO gadata (landing_page, page_title, page_views, visits, visitors, bounce_rate, pageviews_per_visit, time_on_page, avg_time_on_page, day, month, year, hour) VALUES "; 
foreach ($all_data_rows as $data) { 
    if ($i==0) $value=""; else $value=","; 
    $sql.=$value."(:landing_page$i, :page_title$i, :page_views$i, :visits$i, :visitors$i, :bounce_rate$i, :pageviews_per_visit$i, :time_on_page$i, :avg_time_on_page$i, :day$i, :month$i, :year$i, :hour$i)"; 
    $i++; 
} 
$i=0; 
$q=$db_handler->prepare($sql); 
foreach ($all_data_rows as $data) { 
    foreach ($data as $k => $v) { 
    $q->bindValue(":$k$i", $v); 
    } 
    $i++; 
} 
$q->execute(); 
  • 使用臨時表以避免鎖定和磁盤開銷

首先創建HEAP類型的臨時表具有相同的結構爲目標表,然後插入到它:這將是更快,因爲沒有鎖定和磁盤IO發生。然後運行

INSERT INTO final_table SELECT * FROM temporary_table 

如果緩解不夠,您需要考慮在此用例中使用非參數化查詢。通常的注意事項適用。

2

它不是PDO,也不是你插入的方式,使插入如此延遲,但innodb引擎。所以你有3個選擇:

  1. 將所有插入包裝到事務中。
  2. 使用root權限,設置innodb_flush_log_at_trx_commit變量2,使InnoDB的使用寫入filecache - 它會讓你插入速度極快。
  3. 運行在一個查詢中的所有插入件通過馬努所建議
+0

謝謝,我會嘗試將所有插入事務包裝進去:) – hungneox 2013-04-07 13:31:11

+0

您需要提一下,innodb_flush_log_at_trx_commit使InnoDB不符合ACID標準(在最後寫入時刪除D) – 2013-04-07 18:22:31