2012-07-11 61 views
0

我目前正在創建一個批處理腳本,調用多個PHP腳本(即使用笨)從一個數據庫,對結果的工作拉的數據和結果插入另一個數據庫。首先,我知道這可能不是這項工作的最佳工具,但它現在必須做。 但是回到主題,腳本運行良好,性能非常好,除了一種方法。它從第一個數據庫中提取數據,並將其插入到第二個數據庫中。這是一張大約有20列和35000行的表格。笨大批量插入

我用一個簡單的$this->db->insert_batch('tablename', $insertdata);功能插入這些結果,但不知何故,該腳本大約需要15分鐘來執行......

的問題是,如何優化這一進程?

在此先感謝

編輯

這裏是我用來在第二DB創建表的查詢,數據庫的數據被插入。

CREATE TABLE IF NOT EXISTS `invoices` (
    `invoice_number` varchar(40) NOT NULL, 
    `shippinglist_number` varchar(40) DEFAULT NULL, 
    `shippinglist_line` varchar(255) DEFAULT NULL, 
    `customer_id` varchar(5) NOT NULL, 
    `deptor` varchar(5) NOT NULL, 
    `vat_number` int(255) DEFAULT NULL, 
    `invoice_date` date NOT NULL, 
    `expire_date` date NULL DEFAULT NULL, 
    `currency_code` varchar(10) NOT NULL, 
    `subtotal` decimal(19,4) NOT NULL, 
    `vat` decimal(19,4) NOT NULL, 
    `total` decimal(19,4) NOT NULL, 
    `qty` int(10) NOT NULL, 
    `partcode` varchar(255) NOT NULL, 
    `description` text, 
    `price` decimal(19,4) NOT NULL, 
    `pieces_per` int(10) NOT NULL, 
    `article_customer` varchar(255) DEFAULT NULL, 
    `reference_customer` varchar(255) DEFAULT NULL, 
    `sales_line_1` text, 
    `sales_line_2` text, 
    `sales_line_3` text, 
    `memo` text, 
    KEY `invoice_number` (`invoice_number`,`customer_id`,`deptor`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1; 

而查詢只是一個正常的插入,但35000行被切成100行集。

+0

請發佈您的查詢和表架構。 – 2012-07-11 05:52:02

+0

桌子上創建了多少個索引和鍵?它不應該花這麼多時間? – 2013-01-15 07:29:01

回答

0

使用

$x = $this->db->num_rows(); 
for($i=0;$i<$x;$i=$i+30) 
    { 
    $this->db//query stuff 
    $this->db->limit($i); 
    $other->db->//insert stuff 
    } 

您可以通過線做線這樣,你是不依賴於一個巨大的SQL查詢嘗試。 這樣,如果發生錯誤或超時,您可以隨時重新啓動。

數據庫是否在同一臺服務器上?然後,你可以只使用查詢到的數據與選擇從其他數據庫(如果同一用戶同時訪問)

+0

數據庫不在同一臺服務器上,並且一臺服務器不支持限制,所以我不能限制選擇查詢,但codeigniter'insert_batch'函數將查詢分批切換到100本身,所以它有點像做了什麼你說。 – Crinsane 2012-07-11 06:03:00

+0

那麼,15分鐘是你可以期望的35000行,一端選擇運行,另一端插入。 您可以優化的唯一方法是查看值是否已更改/記住最後一個索引,並只更新插入到數據庫中的較新字段。 但是,只有當這不是備份時纔有效。如果是備份,則需要整個表格及其所有內容。 也許使用更快的網絡連接和更多的處理能力分配給您正在執行的服務器上的php&sql? – Tschallacka 2012-07-11 07:54:31

2

使用事務複製 - 1提交總是快於350次的提交。

編輯:

基本上,你需要做到以下幾點:

// Fetch (and transform, I suppose) data from Sybase 
// ... 

$this->db->trans_start(); 

// Put your $this->db->insert_batch() calls here 

$this->db->trans_commit(); 
+0

必須讀入。但不知道其中一個數據庫(sybase)是否支持... – Crinsane 2012-07-11 11:24:58

+0

從我的理解 - 您只是從Sybase獲取數據。事務只對寫入類型的查詢有用,所以Sybase不關心你。 – Narf 2012-07-11 14:53:41

+0

好吧,正如我所說的,並不真正瞭解交易,所以將不得不穀歌一點;) – Crinsane 2012-07-12 05:58:46

3

試試這個

// some $datas 

$this->db->trans_start(); 

$_datas = array_chunk($datas, 300); 

foreach ($_datas as $key => $data) { 
    $this->db->insert_batch('table', $data); 
} 

$this->db->trans_complete(); 

拆分陣列。 300,300,300 ....(mysql建議插入微小的數據)。和insert_batch!每300個數據保持交易。就這些。對不起,我不擅長英語。

+0

通常,最好至少包括一個最小的解釋爲什麼代碼應該是你張貼的方式。 – 2014-12-26 06:41:42

+0

對不起,我不擅長英語。但我認爲這段代碼很明確。你拆分數組。 300,300,300 ....(mysql建議插入微小的數據)。和insert_batch!每300個數據保持交易。這就是全部 – 2015-01-15 09:42:18

+0

這不是太不清楚*代碼做了什麼,但是*爲什麼*它以這種方式完成並不是那麼明顯。 (爲什麼是300?'array_chunck'是拼寫的方式,還是存在拼寫錯誤?如果你忽略了分塊,會發生什麼?等等。)答案是有價值的,主要是因爲它們不僅僅解釋了直接上下文。 – 2015-01-15 09:43:52

0

這是舊的文章,但對於那些誰落在這裏,而尋找一個答案,這可能是這個鏈接可以幫助你。

$ this-> db-> save_queries = FALSE;

http://greeneggmedia.com/blog/entry/undocumented-codeigniter

在後臺CI嘗試保存查詢的分析,如果禁用此功能,你可以得到很多的時間。

如果你不喜歡這個答案,請不要downvote。只是想幫助。