2011-03-24 39 views
0

請考慮表bd.nn包含約爲19萬條記錄:更新從表太慢了其中一個記錄

> SELECT n, name, cdf from bd.nn limit 4; 
+-------+-------------------------------+--------+ 
| n  | name       | cdf | 
+-------+-------------------------------+--------+ 
| 10002 | JOJE       | NULL | 
| 10010 | AUGUSTINA      | NULL | 
| 10029 | CARDOS      | NULL | 
| 10037 | DE FRITOS      | NULL | 
+-------+-------------------------------+--------+ 

n主鍵與BTREE類型。

任務是從下表更新字段cdf;

> SELECT * from n_cdf_temp; 
+-------+--------+ 
| n  | cdf | 
+-------+--------+ 
| 10002 | 16  | 
+-------+--------+ 

主鍵在n與BTREE類型。 n字段仍然有char(9)類型,雖然它計劃移動到int類型。

該表只有一個記錄爲例,但也應該有幾百萬行。

我嘗試的命令是,通過這個命令:

UPDATE bd.nn y SET cdf = (SELECT cdf from temp.n_cdf_temp t WHERE t.n = y.n); 

UPDATE bd.nn y SET cdf = (SELECT cdf from temp.n_cdf_temp t WHERE t.n = y.n) WHERE y.n in (SELECT n from temp.n_cdf_temp WHERE cdf IS NOT NULL); 

UPDATE bd.nn y INNER JOIN temp.n_cdf_temp t ON y.n=t.n SET y.cdf = t.cdf; 

UPDATE bd.nn y FORCE KEY (PRIMARY) INNER JOIN temp.n_cdf_temp t ON y.n=t.n SET y.cdf = t.cdf; 

的問題是,此更新需要很長的時間。 在我的開發筆記本電腦(Core 2 Duo)和MyISAM表格中,第四個命令的更新花費了6.5秒,第三個花費了約30秒。 如果n_cdf_temp有1000條記錄,MyISAM引擎需要45秒。

但是在生產服務器上,使用InnoDB表時,n_cdf_temp只有一條記錄時,更新耗時14分鐘。 當n_cdf_temp有1000條記錄時,查詢花了約。 18分鐘。 MySQL版本5.0.67在舊版Linux中P4,1GB RAM。

我還應該做些什麼來大大提高更新性能的可接受時間?

ETA解釋查詢3的SELECT版本:

EXPLAIN SELECT y.n, t.cdf from bd.nn y INNER JOIN temp.n_cdf_temp t ON y.n=t.n\G 
** 1. row id: 1 select_type: SIMPLE table: t type: index possible_keys: PRIMARY key: cdf key_len: 2 ref: NULL rows: 1 Extra: Using index 
** 2. row id: 1 select_type: SIMPLE table: y type: ALL possible_keys: PRIMARY key: NULL key_len: NULL ref: NULL rows: 18744700 Extra: Range checked for each record (index map: 0x1) – 
+0

你可以發佈EXPLAIN SELECT bc.nn y INNER JOIN temp.n.cdf_temp t ON y.n-t.n'和查詢4的類似'EXPLAIN'的結果嗎?此外,你的連接表必須在臨時數據庫?臨時數據庫與bd數據庫在同一臺計算機上嗎? – dnagirl 2011-03-24 12:37:58

+0

EXPLAIN SELECT y.n,t.cdf from bd.nn y INNER JOIN temp.n_cdf_temp t ON y.n = t.n \ G ** 1。行 ID:1個 SELECT_TYPE:SIMPLE 表:噸 類型:指數 possible_keys:PRIMARY 鍵:CDF key_len:2 REF:NULL 行:1 額外:使用索引 ** 2行 ID :1 SELECT_TYPE:SIMPLE 表:Y 類型:ALL possible_keys:PRIMARY 鍵:NULL key_len:NULL REF:NULL 行:18744700 額外:範圍檢查每個記錄(在dex map:0x1) – Luis 2011-03-24 13:15:17

回答

1

在您發佈的EXPLAIN中,它似乎拒絕在您的'y'表上使用索引。在EXPLAIN的第2行中,注意:'key:NULL key_len:NULL'。這兩個表的主鍵的數據類型可能不同嗎?

+0

當場。我已經開始在'temp'表中將'n'改爲'int'的過程,我沒有記得。 1000條記錄現在在0.09秒內更新。非常感謝dnagirl! – Luis 2011-03-24 14:31:18

0

一種方法來解決這個問題:讓2個請求。

一個是: 從n_cdf_temp中選擇cdf WHERE n ='X';

第二個: UPDATE bd.nn y SET cdf ='第一個請求的結果'WHERE n ='X';

當然,這種方法並不理想,但它非常簡單,它的工作原理。

或者你想更新'X'的所有值的表?

+0

我想更新數百萬條記錄...... – Luis 2011-03-24 12:48:04

+0

也許更快地創建新表格的原因是:'select xn,x.name,y.cdf from bd.nn x,n_cdf_temp y WHERE xn = yn;'?但我認爲,如果你想操縱數百萬條記錄 - 你必須準備好它會很慢。檢查是否使用了字段'n'的索引 – 2011-03-24 13:43:43